MegaBites-AI/Windows-powershell
0372
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System.Diagnostics;5using System.Globalization;6using System.Runtime.CompilerServices;7using System.Runtime.InteropServices;8 9using System.Management.Automation.ComInterop;10 11namespace System.Management.Automation.InteropServices12{13 internal partial struct Variant14 {15 // VT_I116 17 public void SetAsByrefI1(ref sbyte value)18 {19 SetAsByref(ref value, VarEnum.VT_I1);20 }21 22 // VT_I223 24 public void SetAsByrefI2(ref short value)25 {26 SetAsByref(ref value, VarEnum.VT_I2);27 }28 29 // VT_I430 31 public void SetAsByrefI4(ref int value)32 {33 SetAsByref(ref value, VarEnum.VT_I4);34 }35 36 // VT_I837 38 public void SetAsByrefI8(ref long value)39 {40 SetAsByref(ref value, VarEnum.VT_I8);41 }42 43 // VT_UI144 45 public void SetAsByrefUi1(ref byte value)46 {47 SetAsByref(ref value, VarEnum.VT_UI1);48 }49 50 // VT_UI251 52 public void SetAsByrefUi2(ref ushort value)53 {54 SetAsByref(ref value, VarEnum.VT_UI2);55 }56 57 // VT_UI458 59 public void SetAsByrefUi4(ref uint value)60 {61 SetAsByref(ref value, VarEnum.VT_UI4);62 }63 64 // VT_UI865 66 public void SetAsByrefUi8(ref ulong value)67 {68 SetAsByref(ref value, VarEnum.VT_UI8);69 }70 71 // VT_INT72 73 public void SetAsByrefInt(ref int value)74 {75 SetAsByref(ref value, VarEnum.VT_INT);76 }77 78 // VT_UINT79 80 public void SetAsByrefUint(ref uint value)81 {82 SetAsByref(ref value, VarEnum.VT_UINT);83 }84 85 // VT_BOOL86 87 public void SetAsByrefBool(ref short value)88 {89 SetAsByref(ref value, VarEnum.VT_BOOL);90 }91 92 // VT_ERROR93 94 public void SetAsByrefError(ref int value)95 {96 SetAsByref(ref value, VarEnum.VT_ERROR);97 }98 99 // VT_R4100 101 public void SetAsByrefR4(ref float value)102 {103 SetAsByref(ref value, VarEnum.VT_R4);104 }105 106 // VT_R8107 108 public void SetAsByrefR8(ref double value)109 {110 SetAsByref(ref value, VarEnum.VT_R8);111 }112 113 // VT_DECIMAL114 115 public void SetAsByrefDecimal(ref decimal value)116 {117 SetAsByref(ref value, VarEnum.VT_DECIMAL);118 }119 120 // VT_CY121 122 public void SetAsByrefCy(ref long value)123 {124 SetAsByref(ref value, VarEnum.VT_CY);125 }126 127 // VT_DATE128 129 public void SetAsByrefDate(ref double value)130 {131 SetAsByref(ref value, VarEnum.VT_DATE);132 }133 134 // VT_BSTR135 136 public void SetAsByrefBstr(ref IntPtr value)137 {138 SetAsByref(ref value, VarEnum.VT_BSTR);139 }140 141 // VT_UNKNOWN142 143 public void SetAsByrefUnknown(ref IntPtr value)144 {145 SetAsByref(ref value, VarEnum.VT_UNKNOWN);146 }147 148 // VT_DISPATCH149 150 public void SetAsByrefDispatch(ref IntPtr value)151 {152 SetAsByref(ref value, VarEnum.VT_DISPATCH);153 }154 155 // VT_VARIANT156 157 public object AsVariant158 {159 get160 {161 return Marshal.GetObjectForNativeVariant(UnsafeMethods.ConvertVariantByrefToPtr(ref this));162 }163 164 set165 {166 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise167 if (value != null)168 {169 UnsafeMethods.InitVariantForObject(value, ref this);170 }171 }172 }173 174 public void SetAsByrefVariant(ref Variant value)175 {176 SetAsByref(ref value, VarEnum.VT_VARIANT);177 }178 179 // constructs a ByRef variant to pass contents of another variant ByRef.180 public unsafe void SetAsByrefVariantIndirect(ref Variant value)181 {182 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise183 Debug.Assert((value.VariantType & VarEnum.VT_BYREF) == 0, "double indirection");184 185 switch (value.VariantType)186 {187 case VarEnum.VT_EMPTY:188 case VarEnum.VT_NULL:189 // these cannot combine with VT_BYREF. Should try passing as a variant reference190 SetAsByrefVariant(ref value);191 return;192 case VarEnum.VT_RECORD:193 // VT_RECORD's are weird in that regardless of is the VT_BYREF flag is set or not194 // they have the same internal representation.195 _typeUnion._unionTypes._record = value._typeUnion._unionTypes._record;196 break;197 case VarEnum.VT_DECIMAL:198 _typeUnion._unionTypes._byref = (IntPtr)Unsafe.AsPointer(ref value._decimal);199 break;200 default:201 _typeUnion._unionTypes._byref = (IntPtr)Unsafe.AsPointer(ref value._typeUnion._unionTypes._byref);202 break;203 }204 VariantType = (value.VariantType | VarEnum.VT_BYREF);205 }206 207 private unsafe void SetAsByref<T>(ref T value, VarEnum type)208 {209 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise210 VariantType = type | VarEnum.VT_BYREF;211 _typeUnion._unionTypes._byref = (IntPtr)Unsafe.AsPointer<T>(ref value);212 }213 214 internal static System.Reflection.PropertyInfo GetAccessor(VarEnum varType)215 {216 switch (varType)217 {218 case VarEnum.VT_I1: return typeof(Variant).GetProperty(nameof(AsI1));219 case VarEnum.VT_I2: return typeof(Variant).GetProperty(nameof(AsI2));220 case VarEnum.VT_I4: return typeof(Variant).GetProperty(nameof(AsI4));221 case VarEnum.VT_I8: return typeof(Variant).GetProperty(nameof(AsI8));222 case VarEnum.VT_UI1: return typeof(Variant).GetProperty(nameof(AsUi1));223 case VarEnum.VT_UI2: return typeof(Variant).GetProperty(nameof(AsUi2));224 case VarEnum.VT_UI4: return typeof(Variant).GetProperty(nameof(AsUi4));225 case VarEnum.VT_UI8: return typeof(Variant).GetProperty(nameof(AsUi8));226 case VarEnum.VT_INT: return typeof(Variant).GetProperty(nameof(AsInt));227 case VarEnum.VT_UINT: return typeof(Variant).GetProperty(nameof(AsUint));228 case VarEnum.VT_BOOL: return typeof(Variant).GetProperty(nameof(AsBool));229 case VarEnum.VT_ERROR: return typeof(Variant).GetProperty(nameof(AsError));230 case VarEnum.VT_R4: return typeof(Variant).GetProperty(nameof(AsR4));231 case VarEnum.VT_R8: return typeof(Variant).GetProperty(nameof(AsR8));232 case VarEnum.VT_DECIMAL: return typeof(Variant).GetProperty(nameof(AsDecimal));233 case VarEnum.VT_CY: return typeof(Variant).GetProperty(nameof(AsCy));234 case VarEnum.VT_DATE: return typeof(Variant).GetProperty(nameof(AsDate));235 case VarEnum.VT_BSTR: return typeof(Variant).GetProperty(nameof(AsBstr));236 case VarEnum.VT_UNKNOWN: return typeof(Variant).GetProperty(nameof(AsUnknown));237 case VarEnum.VT_DISPATCH: return typeof(Variant).GetProperty(nameof(AsDispatch));238 239 case VarEnum.VT_VARIANT:240 case VarEnum.VT_RECORD:241 case VarEnum.VT_ARRAY:242 return typeof(Variant).GetProperty(nameof(AsVariant));243 244 default:245 throw new NotSupportedException();246 }247 }248 249 internal static System.Reflection.MethodInfo GetByrefSetter(VarEnum varType)250 {251 switch (varType)252 {253 case VarEnum.VT_I1: return typeof(Variant).GetMethod(nameof(SetAsByrefI1));254 case VarEnum.VT_I2: return typeof(Variant).GetMethod(nameof(SetAsByrefI2));255 case VarEnum.VT_I4: return typeof(Variant).GetMethod(nameof(SetAsByrefI4));256 case VarEnum.VT_I8: return typeof(Variant).GetMethod(nameof(SetAsByrefI8));257 case VarEnum.VT_UI1: return typeof(Variant).GetMethod(nameof(SetAsByrefUi1));258 case VarEnum.VT_UI2: return typeof(Variant).GetMethod(nameof(SetAsByrefUi2));259 case VarEnum.VT_UI4: return typeof(Variant).GetMethod(nameof(SetAsByrefUi4));260 case VarEnum.VT_UI8: return typeof(Variant).GetMethod(nameof(SetAsByrefUi8));261 case VarEnum.VT_INT: return typeof(Variant).GetMethod(nameof(SetAsByrefInt));262 case VarEnum.VT_UINT: return typeof(Variant).GetMethod(nameof(SetAsByrefUint));263 case VarEnum.VT_BOOL: return typeof(Variant).GetMethod(nameof(SetAsByrefBool));264 case VarEnum.VT_ERROR: return typeof(Variant).GetMethod(nameof(SetAsByrefError));265 case VarEnum.VT_R4: return typeof(Variant).GetMethod(nameof(SetAsByrefR4));266 case VarEnum.VT_R8: return typeof(Variant).GetMethod(nameof(SetAsByrefR8));267 case VarEnum.VT_DECIMAL: return typeof(Variant).GetMethod(nameof(SetAsByrefDecimal));268 case VarEnum.VT_CY: return typeof(Variant).GetMethod(nameof(SetAsByrefCy));269 case VarEnum.VT_DATE: return typeof(Variant).GetMethod(nameof(SetAsByrefDate));270 case VarEnum.VT_BSTR: return typeof(Variant).GetMethod(nameof(SetAsByrefBstr));271 case VarEnum.VT_UNKNOWN: return typeof(Variant).GetMethod(nameof(SetAsByrefUnknown));272 case VarEnum.VT_DISPATCH: return typeof(Variant).GetMethod(nameof(SetAsByrefDispatch));273 274 case VarEnum.VT_VARIANT:275 return typeof(Variant).GetMethod(nameof(SetAsByrefVariant));276 case VarEnum.VT_RECORD:277 case VarEnum.VT_ARRAY:278 return typeof(Variant).GetMethod(nameof(SetAsByrefVariantIndirect));279 280 default:281 throw new NotSupportedException();282 }283 }284 285 public override string ToString() => $"Variant ({VariantType})";286 287 public void SetAsIConvertible(IConvertible value)288 {289 Debug.Assert(IsEmpty); // The setter can only be called once as VariantClear might be needed otherwise290 291 TypeCode tc = value.GetTypeCode();292 CultureInfo ci = CultureInfo.CurrentCulture;293 294 switch (tc)295 {296 case TypeCode.Empty: break;297 case TypeCode.Object: AsUnknown = value; break;298 case TypeCode.DBNull: SetAsNULL(); break;299 case TypeCode.Boolean: AsBool = value.ToBoolean(ci); break;300 case TypeCode.Char: AsUi2 = value.ToChar(ci); break;301 case TypeCode.SByte: AsI1 = value.ToSByte(ci); break;302 case TypeCode.Byte: AsUi1 = value.ToByte(ci); break;303 case TypeCode.Int16: AsI2 = value.ToInt16(ci); break;304 case TypeCode.UInt16: AsUi2 = value.ToUInt16(ci); break;305 case TypeCode.Int32: AsI4 = value.ToInt32(ci); break;306 case TypeCode.UInt32: AsUi4 = value.ToUInt32(ci); break;307 case TypeCode.Int64: AsI8 = value.ToInt64(ci); break;308 case TypeCode.UInt64: AsI8 = value.ToInt64(ci); break;309 case TypeCode.Single: AsR4 = value.ToSingle(ci); break;310 case TypeCode.Double: AsR8 = value.ToDouble(ci); break;311 case TypeCode.Decimal: AsDecimal = value.ToDecimal(ci); break;312 case TypeCode.DateTime: AsDate = value.ToDateTime(ci); break;313 case TypeCode.String: AsBstr = value.ToString(ci); break;314 315 default:316 throw new NotSupportedException();317 }318 }319 }320}321 