1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 #if !SILVERLIGHT // ComObject
20 using System.Diagnostics;
21 using System.Diagnostics.CodeAnalysis;
22 using System.Globalization;
23 using System.Runtime.InteropServices;
24 using System.Security;
25 using System.Security.Permissions;
28 namespace System.Dynamic {
30 namespace Microsoft.Scripting {
34 /// Variant is the basic COM type for late-binding. It can contain any other COM data type.
35 /// This type definition precisely matches the unmanaged data layout so that the struct can be passed
36 /// to and from COM calls.
38 [StructLayout(LayoutKind.Explicit)]
39 internal struct Variant {
42 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2207:InitializeValueTypeStaticFieldsInline")]
44 // Variant size is the size of 4 pointers (16 bytes) on a 32-bit processor,
45 // and 3 pointers (24 bytes) on a 64-bit processor.
46 int intPtrSize = Marshal.SizeOf(typeof(IntPtr));
47 int variantSize = Marshal.SizeOf(typeof(Variant));
48 if (intPtrSize == 4) {
49 Debug.Assert(variantSize == (4 * intPtrSize));
51 Debug.Assert(intPtrSize == 8);
52 Debug.Assert(variantSize == (3 * intPtrSize));
57 // Most of the data types in the Variant are carried in _typeUnion
59 private TypeUnion _typeUnion;
61 // Decimal is the largest data type and it needs to use the space that is normally unused in TypeUnion._wReserved1, etc.
62 // Hence, it is declared to completely overlap with TypeUnion. A Decimal does not use the first two bytes, and so
63 // TypeUnion._vt can still be used to encode the type.
65 private Decimal _decimal;
67 [StructLayout(LayoutKind.Sequential)]
68 private struct TypeUnion {
70 internal ushort _wReserved1;
71 internal ushort _wReserved2;
72 internal ushort _wReserved3;
74 internal UnionTypes _unionTypes;
77 [StructLayout(LayoutKind.Sequential)]
78 private struct Record {
79 private IntPtr _record;
80 private IntPtr _recordInfo;
83 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")]
84 [StructLayout(LayoutKind.Explicit)]
85 private struct UnionTypes {
86 #region Generated Variant union types
88 // *** BEGIN GENERATED CODE ***
89 // generated by function: gen_UnionTypes from: generate_comdispatch.py
91 [FieldOffset(0)] internal SByte _i1;
92 [FieldOffset(0)] internal Int16 _i2;
93 [FieldOffset(0)] internal Int32 _i4;
94 [FieldOffset(0)] internal Int64 _i8;
95 [FieldOffset(0)] internal Byte _ui1;
96 [FieldOffset(0)] internal UInt16 _ui2;
97 [FieldOffset(0)] internal UInt32 _ui4;
98 [FieldOffset(0)] internal UInt64 _ui8;
99 [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
100 [FieldOffset(0)] internal IntPtr _int;
101 [FieldOffset(0)] internal UIntPtr _uint;
102 [FieldOffset(0)] internal Int16 _bool;
103 [FieldOffset(0)] internal Int32 _error;
104 [FieldOffset(0)] internal Single _r4;
105 [FieldOffset(0)] internal Double _r8;
106 [FieldOffset(0)] internal Int64 _cy;
107 [FieldOffset(0)] internal Double _date;
108 [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
109 [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
110 [FieldOffset(0)] internal IntPtr _bstr;
111 [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
112 [FieldOffset(0)] internal IntPtr _unknown;
113 [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
114 [FieldOffset(0)] internal IntPtr _dispatch;
116 // *** END GENERATED CODE ***
120 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
122 internal IntPtr _byref;
123 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
125 internal Record _record;
128 public override string ToString() {
129 return String.Format(CultureInfo.CurrentCulture, "Variant ({0})", VariantType);
133 /// Primitive types are the basic COM types. It includes valuetypes like ints, but also reference types
134 /// like BStrs. It does not include composite types like arrays and user-defined COM types (IUnknown/IDispatch).
136 internal static bool IsPrimitiveType(VarEnum varEnum) {
138 #region Generated Variant IsPrimitiveType
140 // *** BEGIN GENERATED CODE ***
141 // generated by function: gen_IsPrimitiveType from: generate_comdispatch.py
152 case VarEnum.VT_UINT:
153 case VarEnum.VT_BOOL:
154 case VarEnum.VT_ERROR:
157 case VarEnum.VT_DECIMAL:
159 case VarEnum.VT_DATE:
160 case VarEnum.VT_BSTR:
162 // *** END GENERATED CODE ***
172 /// Get the managed object representing the Variant.
174 /// <returns></returns>
175 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
176 #if MICROSOFT_DYNAMIC
177 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
180 public object ToObject() {
181 // Check the simple case upfront
186 switch (VariantType) {
187 case VarEnum.VT_NULL: return DBNull.Value;
189 #region Generated Variant ToObject
191 // *** BEGIN GENERATED CODE ***
192 // generated by function: gen_ToObject from: generate_comdispatch.py
194 case VarEnum.VT_I1: return AsI1;
195 case VarEnum.VT_I2: return AsI2;
196 case VarEnum.VT_I4: return AsI4;
197 case VarEnum.VT_I8: return AsI8;
198 case VarEnum.VT_UI1: return AsUi1;
199 case VarEnum.VT_UI2: return AsUi2;
200 case VarEnum.VT_UI4: return AsUi4;
201 case VarEnum.VT_UI8: return AsUi8;
202 case VarEnum.VT_INT: return AsInt;
203 case VarEnum.VT_UINT: return AsUint;
204 case VarEnum.VT_BOOL: return AsBool;
205 case VarEnum.VT_ERROR: return AsError;
206 case VarEnum.VT_R4: return AsR4;
207 case VarEnum.VT_R8: return AsR8;
208 case VarEnum.VT_DECIMAL: return AsDecimal;
209 case VarEnum.VT_CY: return AsCy;
210 case VarEnum.VT_DATE: return AsDate;
211 case VarEnum.VT_BSTR: return AsBstr;
212 case VarEnum.VT_UNKNOWN: return AsUnknown;
213 case VarEnum.VT_DISPATCH: return AsDispatch;
214 case VarEnum.VT_VARIANT: return AsVariant;
216 // *** END GENERATED CODE ***
226 /// Release any unmanaged memory associated with the Variant
228 /// <returns></returns>
229 #if MICROSOFT_DYNAMIC
230 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
233 public void Clear() {
234 // We do not need to call OLE32's VariantClear for primitive types or ByRefs
235 // to safe ourselves the cost of interop transition.
236 // ByRef indicates the memory is not owned by the VARIANT itself while
237 // primitive types do not have any resources to free up.
238 // Hence, only safearrays, BSTRs, interfaces and user types are
239 // handled differently.
240 VarEnum vt = VariantType;
241 if ((vt & VarEnum.VT_BYREF) != 0) {
242 VariantType = VarEnum.VT_EMPTY;
244 ((vt & VarEnum.VT_ARRAY) != 0) ||
245 ((vt) == VarEnum.VT_BSTR) ||
246 ((vt) == VarEnum.VT_UNKNOWN) ||
247 ((vt) == VarEnum.VT_DISPATCH) ||
248 ((vt) == VarEnum.VT_RECORD)
250 IntPtr variantPtr = UnsafeMethods.ConvertVariantByrefToPtr(ref this);
251 NativeMethods.VariantClear(variantPtr);
252 Debug.Assert(IsEmpty);
254 VariantType = VarEnum.VT_EMPTY;
258 public VarEnum VariantType {
260 return (VarEnum)_typeUnion._vt;
263 _typeUnion._vt = (ushort)value;
267 internal bool IsEmpty {
269 return _typeUnion._vt == ((ushort)VarEnum.VT_EMPTY);
273 public void SetAsNull() {
274 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
275 VariantType = VarEnum.VT_NULL;
278 #if MICROSOFT_DYNAMIC
279 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
282 public void SetAsIConvertible(IConvertible value) {
283 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
285 TypeCode tc = value.GetTypeCode();
286 CultureInfo ci = CultureInfo.CurrentCulture;
289 case TypeCode.Empty: break;
290 case TypeCode.Object: AsUnknown = value; break;
291 case TypeCode.DBNull: SetAsNull(); break;
292 case TypeCode.Boolean: AsBool = value.ToBoolean(ci); break;
293 case TypeCode.Char: AsUi2 = value.ToChar(ci); break;
294 case TypeCode.SByte: AsI1 = value.ToSByte(ci); break;
295 case TypeCode.Byte: AsUi1 = value.ToByte(ci); break;
296 case TypeCode.Int16: AsI2 = value.ToInt16(ci); break;
297 case TypeCode.UInt16: AsUi2 = value.ToUInt16(ci); break;
298 case TypeCode.Int32: AsI4 = value.ToInt32(ci); break;
299 case TypeCode.UInt32: AsUi4 = value.ToUInt32(ci); break;
300 case TypeCode.Int64: AsI8 = value.ToInt64(ci); break;
301 case TypeCode.UInt64: AsI8 = value.ToInt64(ci); break;
302 case TypeCode.Single: AsR4 = value.ToSingle(ci); break;
303 case TypeCode.Double: AsR8 = value.ToDouble(ci); break;
304 case TypeCode.Decimal: AsDecimal = value.ToDecimal(ci); break;
305 case TypeCode.DateTime: AsDate = value.ToDateTime(ci); break;
306 case TypeCode.String: AsBstr = value.ToString(ci); break;
309 throw Assert.Unreachable;
313 #region Generated Variant accessors
315 // *** BEGIN GENERATED CODE ***
316 // generated by function: gen_accessors from: generate_comdispatch.py
321 Debug.Assert(VariantType == VarEnum.VT_I1);
322 return _typeUnion._unionTypes._i1;
325 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
326 VariantType = VarEnum.VT_I1;
327 _typeUnion._unionTypes._i1 = value;
331 #if MICROSOFT_DYNAMIC
332 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
335 public void SetAsByrefI1(ref SByte value) {
336 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
337 VariantType = (VarEnum.VT_I1 | VarEnum.VT_BYREF);
338 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertSByteByrefToPtr(ref value);
344 Debug.Assert(VariantType == VarEnum.VT_I2);
345 return _typeUnion._unionTypes._i2;
348 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
349 VariantType = VarEnum.VT_I2;
350 _typeUnion._unionTypes._i2 = value;
354 #if MICROSOFT_DYNAMIC
355 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
358 public void SetAsByrefI2(ref Int16 value) {
359 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
360 VariantType = (VarEnum.VT_I2 | VarEnum.VT_BYREF);
361 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt16ByrefToPtr(ref value);
367 Debug.Assert(VariantType == VarEnum.VT_I4);
368 return _typeUnion._unionTypes._i4;
371 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
372 VariantType = VarEnum.VT_I4;
373 _typeUnion._unionTypes._i4 = value;
377 #if MICROSOFT_DYNAMIC
378 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
381 public void SetAsByrefI4(ref Int32 value) {
382 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
383 VariantType = (VarEnum.VT_I4 | VarEnum.VT_BYREF);
384 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt32ByrefToPtr(ref value);
390 Debug.Assert(VariantType == VarEnum.VT_I8);
391 return _typeUnion._unionTypes._i8;
394 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
395 VariantType = VarEnum.VT_I8;
396 _typeUnion._unionTypes._i8 = value;
400 #if MICROSOFT_DYNAMIC
401 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
404 public void SetAsByrefI8(ref Int64 value) {
405 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
406 VariantType = (VarEnum.VT_I8 | VarEnum.VT_BYREF);
407 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt64ByrefToPtr(ref value);
413 Debug.Assert(VariantType == VarEnum.VT_UI1);
414 return _typeUnion._unionTypes._ui1;
417 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
418 VariantType = VarEnum.VT_UI1;
419 _typeUnion._unionTypes._ui1 = value;
423 #if MICROSOFT_DYNAMIC
424 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
427 public void SetAsByrefUi1(ref Byte value) {
428 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
429 VariantType = (VarEnum.VT_UI1 | VarEnum.VT_BYREF);
430 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertByteByrefToPtr(ref value);
434 public UInt16 AsUi2 {
436 Debug.Assert(VariantType == VarEnum.VT_UI2);
437 return _typeUnion._unionTypes._ui2;
440 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
441 VariantType = VarEnum.VT_UI2;
442 _typeUnion._unionTypes._ui2 = value;
446 #if MICROSOFT_DYNAMIC
447 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
450 public void SetAsByrefUi2(ref UInt16 value) {
451 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
452 VariantType = (VarEnum.VT_UI2 | VarEnum.VT_BYREF);
453 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertUInt16ByrefToPtr(ref value);
457 public UInt32 AsUi4 {
459 Debug.Assert(VariantType == VarEnum.VT_UI4);
460 return _typeUnion._unionTypes._ui4;
463 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
464 VariantType = VarEnum.VT_UI4;
465 _typeUnion._unionTypes._ui4 = value;
469 #if MICROSOFT_DYNAMIC
470 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
473 public void SetAsByrefUi4(ref UInt32 value) {
474 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
475 VariantType = (VarEnum.VT_UI4 | VarEnum.VT_BYREF);
476 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertUInt32ByrefToPtr(ref value);
480 public UInt64 AsUi8 {
482 Debug.Assert(VariantType == VarEnum.VT_UI8);
483 return _typeUnion._unionTypes._ui8;
486 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
487 VariantType = VarEnum.VT_UI8;
488 _typeUnion._unionTypes._ui8 = value;
492 #if MICROSOFT_DYNAMIC
493 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
496 public void SetAsByrefUi8(ref UInt64 value) {
497 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
498 VariantType = (VarEnum.VT_UI8 | VarEnum.VT_BYREF);
499 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertUInt64ByrefToPtr(ref value);
503 public IntPtr AsInt {
505 Debug.Assert(VariantType == VarEnum.VT_INT);
506 return _typeUnion._unionTypes._int;
509 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
510 VariantType = VarEnum.VT_INT;
511 _typeUnion._unionTypes._int = value;
515 #if MICROSOFT_DYNAMIC
516 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
519 public void SetAsByrefInt(ref IntPtr value) {
520 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
521 VariantType = (VarEnum.VT_INT | VarEnum.VT_BYREF);
522 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertIntPtrByrefToPtr(ref value);
526 public UIntPtr AsUint {
528 Debug.Assert(VariantType == VarEnum.VT_UINT);
529 return _typeUnion._unionTypes._uint;
532 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
533 VariantType = VarEnum.VT_UINT;
534 _typeUnion._unionTypes._uint = value;
538 #if MICROSOFT_DYNAMIC
539 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
542 public void SetAsByrefUint(ref UIntPtr value) {
543 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
544 VariantType = (VarEnum.VT_UINT | VarEnum.VT_BYREF);
545 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertUIntPtrByrefToPtr(ref value);
549 public Boolean AsBool {
551 Debug.Assert(VariantType == VarEnum.VT_BOOL);
552 return _typeUnion._unionTypes._bool != 0;
555 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
556 VariantType = VarEnum.VT_BOOL;
557 _typeUnion._unionTypes._bool = value ? (Int16)(-1) : (Int16)0;
561 #if MICROSOFT_DYNAMIC
562 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
565 public void SetAsByrefBool(ref Int16 value) {
566 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
567 VariantType = (VarEnum.VT_BOOL | VarEnum.VT_BYREF);
568 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt16ByrefToPtr(ref value);
572 public Int32 AsError {
574 Debug.Assert(VariantType == VarEnum.VT_ERROR);
575 return _typeUnion._unionTypes._error;
578 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
579 VariantType = VarEnum.VT_ERROR;
580 _typeUnion._unionTypes._error = value;
584 #if MICROSOFT_DYNAMIC
585 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
588 public void SetAsByrefError(ref Int32 value) {
589 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
590 VariantType = (VarEnum.VT_ERROR | VarEnum.VT_BYREF);
591 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt32ByrefToPtr(ref value);
597 Debug.Assert(VariantType == VarEnum.VT_R4);
598 return _typeUnion._unionTypes._r4;
601 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
602 VariantType = VarEnum.VT_R4;
603 _typeUnion._unionTypes._r4 = value;
607 #if MICROSOFT_DYNAMIC
608 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
611 public void SetAsByrefR4(ref Single value) {
612 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
613 VariantType = (VarEnum.VT_R4 | VarEnum.VT_BYREF);
614 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertSingleByrefToPtr(ref value);
620 Debug.Assert(VariantType == VarEnum.VT_R8);
621 return _typeUnion._unionTypes._r8;
624 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
625 VariantType = VarEnum.VT_R8;
626 _typeUnion._unionTypes._r8 = value;
630 #if MICROSOFT_DYNAMIC
631 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
634 public void SetAsByrefR8(ref Double value) {
635 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
636 VariantType = (VarEnum.VT_R8 | VarEnum.VT_BYREF);
637 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertDoubleByrefToPtr(ref value);
641 public Decimal AsDecimal {
643 Debug.Assert(VariantType == VarEnum.VT_DECIMAL);
644 // The first byte of Decimal is unused, but usually set to 0
646 v._typeUnion._vt = 0;
650 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
651 VariantType = VarEnum.VT_DECIMAL;
653 // _vt overlaps with _decimal, and should be set after setting _decimal
654 _typeUnion._vt = (ushort)VarEnum.VT_DECIMAL;
658 #if MICROSOFT_DYNAMIC
659 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
662 public void SetAsByrefDecimal(ref Decimal value) {
663 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
664 VariantType = (VarEnum.VT_DECIMAL | VarEnum.VT_BYREF);
665 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertDecimalByrefToPtr(ref value);
669 public Decimal AsCy {
671 Debug.Assert(VariantType == VarEnum.VT_CY);
672 return Decimal.FromOACurrency(_typeUnion._unionTypes._cy);
675 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
676 VariantType = VarEnum.VT_CY;
677 _typeUnion._unionTypes._cy = Decimal.ToOACurrency(value);
681 #if MICROSOFT_DYNAMIC
682 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
685 public void SetAsByrefCy(ref Int64 value) {
686 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
687 VariantType = (VarEnum.VT_CY | VarEnum.VT_BYREF);
688 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertInt64ByrefToPtr(ref value);
692 public DateTime AsDate {
694 Debug.Assert(VariantType == VarEnum.VT_DATE);
695 return DateTime.FromOADate(_typeUnion._unionTypes._date);
698 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
699 VariantType = VarEnum.VT_DATE;
700 _typeUnion._unionTypes._date = value.ToOADate();
704 #if MICROSOFT_DYNAMIC
705 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
708 public void SetAsByrefDate(ref Double value) {
709 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
710 VariantType = (VarEnum.VT_DATE | VarEnum.VT_BYREF);
711 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertDoubleByrefToPtr(ref value);
715 public String AsBstr {
716 #if MICROSOFT_DYNAMIC
717 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
721 Debug.Assert(VariantType == VarEnum.VT_BSTR);
722 if (_typeUnion._unionTypes._bstr != IntPtr.Zero) {
723 return Marshal.PtrToStringBSTR(_typeUnion._unionTypes._bstr);
728 #if MICROSOFT_DYNAMIC
729 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
733 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
734 VariantType = VarEnum.VT_BSTR;
736 Marshal.GetNativeVariantForObject(value, UnsafeMethods.ConvertVariantByrefToPtr(ref this));
741 #if MICROSOFT_DYNAMIC
742 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
745 public void SetAsByrefBstr(ref IntPtr value) {
746 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
747 VariantType = (VarEnum.VT_BSTR | VarEnum.VT_BYREF);
748 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertIntPtrByrefToPtr(ref value);
752 public Object AsUnknown {
753 #if MICROSOFT_DYNAMIC
754 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
758 Debug.Assert(VariantType == VarEnum.VT_UNKNOWN);
759 if (_typeUnion._unionTypes._dispatch != IntPtr.Zero) {
760 return Marshal.GetObjectForIUnknown(_typeUnion._unionTypes._unknown);
765 #if MICROSOFT_DYNAMIC
766 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
770 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
771 VariantType = VarEnum.VT_UNKNOWN;
773 _typeUnion._unionTypes._unknown = Marshal.GetIUnknownForObject(value);
778 #if MICROSOFT_DYNAMIC
779 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
782 public void SetAsByrefUnknown(ref IntPtr value) {
783 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
784 VariantType = (VarEnum.VT_UNKNOWN | VarEnum.VT_BYREF);
785 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertIntPtrByrefToPtr(ref value);
789 public Object AsDispatch {
790 #if MICROSOFT_DYNAMIC
791 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
795 Debug.Assert(VariantType == VarEnum.VT_DISPATCH);
796 if (_typeUnion._unionTypes._dispatch != IntPtr.Zero) {
797 return Marshal.GetObjectForIUnknown(_typeUnion._unionTypes._dispatch);
802 #if MICROSOFT_DYNAMIC
803 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
807 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
808 VariantType = VarEnum.VT_DISPATCH;
810 _typeUnion._unionTypes._unknown = Marshal.GetIDispatchForObject(value);
815 #if MICROSOFT_DYNAMIC
816 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
819 public void SetAsByrefDispatch(ref IntPtr value) {
820 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
821 VariantType = (VarEnum.VT_DISPATCH | VarEnum.VT_BYREF);
822 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertIntPtrByrefToPtr(ref value);
826 // *** END GENERATED CODE ***
833 public Object AsVariant {
834 #if MICROSOFT_DYNAMIC
835 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
839 return Marshal.GetObjectForNativeVariant(UnsafeMethods.ConvertVariantByrefToPtr(ref this));
842 #if MICROSOFT_DYNAMIC
843 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
847 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
849 UnsafeMethods.InitVariantForObject(value, ref this);
854 #if MICROSOFT_DYNAMIC
855 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
858 public void SetAsByrefVariant(ref Variant value) {
859 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
860 VariantType = (VarEnum.VT_VARIANT | VarEnum.VT_BYREF);
861 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertVariantByrefToPtr(ref value);
864 // constructs a ByRef variant to pass contents of another variant ByRef.
865 #if MICROSOFT_DYNAMIC
866 [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
869 public void SetAsByrefVariantIndirect(ref Variant value) {
870 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise
871 Debug.Assert((value.VariantType & VarEnum.VT_BYREF) == 0, "double indirection");
873 switch (value.VariantType) {
874 case VarEnum.VT_EMPTY:
875 case VarEnum.VT_NULL:
876 // these cannot combine with VT_BYREF. Should try passing as a variant reference
877 SetAsByrefVariant(ref value);
879 case VarEnum.VT_RECORD:
880 // VT_RECORD's are weird in that regardless of is the VT_BYREF flag is set or not
881 // they have the same internal representation.
882 _typeUnion._unionTypes._record = value._typeUnion._unionTypes._record;
884 case VarEnum.VT_DECIMAL:
885 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertDecimalByrefToPtr(ref value._decimal);
888 _typeUnion._unionTypes._byref = UnsafeMethods.ConvertIntPtrByrefToPtr(ref value._typeUnion._unionTypes._byref);
891 VariantType = (value.VariantType | VarEnum.VT_BYREF);
894 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
895 internal static System.Reflection.PropertyInfo GetAccessor(VarEnum varType) {
898 #region Generated Variant accessors PropertyInfos
900 // *** BEGIN GENERATED CODE ***
901 // generated by function: gen_accessor_propertyinfo from: generate_comdispatch.py
903 case VarEnum.VT_I1: return typeof(Variant).GetProperty("AsI1");
904 case VarEnum.VT_I2: return typeof(Variant).GetProperty("AsI2");
905 case VarEnum.VT_I4: return typeof(Variant).GetProperty("AsI4");
906 case VarEnum.VT_I8: return typeof(Variant).GetProperty("AsI8");
907 case VarEnum.VT_UI1: return typeof(Variant).GetProperty("AsUi1");
908 case VarEnum.VT_UI2: return typeof(Variant).GetProperty("AsUi2");
909 case VarEnum.VT_UI4: return typeof(Variant).GetProperty("AsUi4");
910 case VarEnum.VT_UI8: return typeof(Variant).GetProperty("AsUi8");
911 case VarEnum.VT_INT: return typeof(Variant).GetProperty("AsInt");
912 case VarEnum.VT_UINT: return typeof(Variant).GetProperty("AsUint");
913 case VarEnum.VT_BOOL: return typeof(Variant).GetProperty("AsBool");
914 case VarEnum.VT_ERROR: return typeof(Variant).GetProperty("AsError");
915 case VarEnum.VT_R4: return typeof(Variant).GetProperty("AsR4");
916 case VarEnum.VT_R8: return typeof(Variant).GetProperty("AsR8");
917 case VarEnum.VT_DECIMAL: return typeof(Variant).GetProperty("AsDecimal");
918 case VarEnum.VT_CY: return typeof(Variant).GetProperty("AsCy");
919 case VarEnum.VT_DATE: return typeof(Variant).GetProperty("AsDate");
920 case VarEnum.VT_BSTR: return typeof(Variant).GetProperty("AsBstr");
921 case VarEnum.VT_UNKNOWN: return typeof(Variant).GetProperty("AsUnknown");
922 case VarEnum.VT_DISPATCH: return typeof(Variant).GetProperty("AsDispatch");
924 // *** END GENERATED CODE ***
928 case VarEnum.VT_VARIANT:
929 case VarEnum.VT_RECORD:
930 case VarEnum.VT_ARRAY:
931 return typeof(Variant).GetProperty("AsVariant");
934 throw Error.VariantGetAccessorNYI(varType);
938 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
939 internal static System.Reflection.MethodInfo GetByrefSetter(VarEnum varType) {
942 #region Generated Variant byref setter
944 // *** BEGIN GENERATED CODE ***
945 // generated by function: gen_byref_setters from: generate_comdispatch.py
947 case VarEnum.VT_I1: return typeof(Variant).GetMethod("SetAsByrefI1");
948 case VarEnum.VT_I2: return typeof(Variant).GetMethod("SetAsByrefI2");
949 case VarEnum.VT_I4: return typeof(Variant).GetMethod("SetAsByrefI4");
950 case VarEnum.VT_I8: return typeof(Variant).GetMethod("SetAsByrefI8");
951 case VarEnum.VT_UI1: return typeof(Variant).GetMethod("SetAsByrefUi1");
952 case VarEnum.VT_UI2: return typeof(Variant).GetMethod("SetAsByrefUi2");
953 case VarEnum.VT_UI4: return typeof(Variant).GetMethod("SetAsByrefUi4");
954 case VarEnum.VT_UI8: return typeof(Variant).GetMethod("SetAsByrefUi8");
955 case VarEnum.VT_INT: return typeof(Variant).GetMethod("SetAsByrefInt");
956 case VarEnum.VT_UINT: return typeof(Variant).GetMethod("SetAsByrefUint");
957 case VarEnum.VT_BOOL: return typeof(Variant).GetMethod("SetAsByrefBool");
958 case VarEnum.VT_ERROR: return typeof(Variant).GetMethod("SetAsByrefError");
959 case VarEnum.VT_R4: return typeof(Variant).GetMethod("SetAsByrefR4");
960 case VarEnum.VT_R8: return typeof(Variant).GetMethod("SetAsByrefR8");
961 case VarEnum.VT_DECIMAL: return typeof(Variant).GetMethod("SetAsByrefDecimal");
962 case VarEnum.VT_CY: return typeof(Variant).GetMethod("SetAsByrefCy");
963 case VarEnum.VT_DATE: return typeof(Variant).GetMethod("SetAsByrefDate");
964 case VarEnum.VT_BSTR: return typeof(Variant).GetMethod("SetAsByrefBstr");
965 case VarEnum.VT_UNKNOWN: return typeof(Variant).GetMethod("SetAsByrefUnknown");
966 case VarEnum.VT_DISPATCH: return typeof(Variant).GetMethod("SetAsByrefDispatch");
968 // *** END GENERATED CODE ***
972 case VarEnum.VT_VARIANT:
973 return typeof(Variant).GetMethod("SetAsByrefVariant");
974 case VarEnum.VT_RECORD:
975 case VarEnum.VT_ARRAY:
976 return typeof(Variant).GetMethod("SetAsByrefVariantIndirect");
979 throw Error.VariantGetAccessorNYI(varType);