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;5using System.Collections;6using System.Collections.Generic;7using System.Runtime.InteropServices.ComTypes;8using System.Threading;9 10namespace System.Management.Automation.ComInterop11{12 internal class ComTypeDesc13 {14 private readonly string _typeName;15 private readonly string _documentation;16 private ComMethodDesc _getItem;17 private ComMethodDesc _setItem;18 19 internal ComTypeDesc(ITypeInfo typeInfo, ComTypeLibDesc typeLibDesc)20 {21 if (typeInfo != null)22 {23 ComRuntimeHelpers.GetInfoFromType(typeInfo, out _typeName, out _documentation);24 }25 TypeLib = typeLibDesc;26 }27 28 internal static ComTypeDesc FromITypeInfo(ITypeInfo typeInfo, TYPEATTR typeAttr)29 {30 switch (typeAttr.typekind)31 {32 case TYPEKIND.TKIND_COCLASS:33 return new ComTypeClassDesc(typeInfo, null);34 case TYPEKIND.TKIND_ENUM:35 return new ComTypeEnumDesc(typeInfo, null);36 case TYPEKIND.TKIND_DISPATCH:37 case TYPEKIND.TKIND_INTERFACE:38 ComTypeDesc typeDesc = new ComTypeDesc(typeInfo, null);39 return typeDesc;40 default:41 throw new InvalidOperationException("Attempting to wrap an unsupported enum type.");42 }43 }44 45 internal static ComTypeDesc CreateEmptyTypeDesc()46 {47 ComTypeDesc typeDesc = new ComTypeDesc(null, null)48 {49 Funcs = new Hashtable(),50 Puts = new Hashtable(),51 PutRefs = new Hashtable(),52 Events = EmptyEvents53 };54 55 return typeDesc;56 }57 58 internal static Dictionary<string, ComEventDesc> EmptyEvents { get; } = new Dictionary<string, ComEventDesc>();59 60 internal Hashtable Funcs { get; set; }61 62 internal Hashtable Puts { get; set; }63 64 internal Hashtable PutRefs { get; set; }65 66 internal Dictionary<string, ComEventDesc> Events { get; set; }67 68 internal bool TryGetFunc(string name, out ComMethodDesc method)69 {70 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);71 if (Funcs.ContainsKey(name))72 {73 method = Funcs[name] as ComMethodDesc;74 return true;75 }76 method = null;77 return false;78 }79 80 internal void AddFunc(string name, ComMethodDesc method)81 {82 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);83 lock (Funcs)84 {85 Funcs[name] = method;86 }87 }88 89 internal bool TryGetPut(string name, out ComMethodDesc method)90 {91 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);92 if (Puts.ContainsKey(name))93 {94 method = Puts[name] as ComMethodDesc;95 return true;96 }97 method = null;98 return false;99 }100 101 internal void AddPut(string name, ComMethodDesc method)102 {103 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);104 lock (Puts)105 {106 Puts[name] = method;107 }108 }109 110 internal bool TryGetPutRef(string name, out ComMethodDesc method)111 {112 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);113 if (PutRefs.ContainsKey(name))114 {115 method = PutRefs[name] as ComMethodDesc;116 return true;117 }118 method = null;119 return false;120 }121 122 internal void AddPutRef(string name, ComMethodDesc method)123 {124 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);125 lock (PutRefs)126 {127 PutRefs[name] = method;128 }129 }130 131 internal bool TryGetEvent(string name, out ComEventDesc @event)132 {133 name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);134 return Events.TryGetValue(name, out @event);135 }136 137 internal string[] GetMemberNames(bool dataOnly)138 {139 var names = new Dictionary<string, object>();140 141 lock (Funcs)142 {143 foreach (ComMethodDesc func in Funcs.Values)144 {145 if (!dataOnly || func.IsDataMember)146 {147 names.Add(func.Name, null);148 }149 }150 }151 152 if (!dataOnly)153 {154 lock (Puts)155 {156 foreach (ComMethodDesc func in Puts.Values)157 {158 if (!names.ContainsKey(func.Name))159 {160 names.Add(func.Name, null);161 }162 }163 }164 165 lock (PutRefs)166 {167 foreach (ComMethodDesc func in PutRefs.Values)168 {169 if (!names.ContainsKey(func.Name))170 {171 names.Add(func.Name, null);172 }173 }174 }175 176 if (Events != null && Events.Count > 0)177 {178 foreach (string name in Events.Keys)179 {180 if (!names.ContainsKey(name))181 {182 names.Add(name, null);183 }184 }185 }186 }187 188 string[] result = new string[names.Keys.Count];189 names.Keys.CopyTo(result, 0);190 return result;191 }192 193 public string TypeName => _typeName;194 195 internal string Documentation => _documentation;196 197 public ComTypeLibDesc TypeLib { get; }198 199 internal Guid Guid { get; set; }200 201 internal ComMethodDesc GetItem => _getItem;202 203 internal void EnsureGetItem(ComMethodDesc candidate)204 {205 Interlocked.CompareExchange(ref _getItem, candidate, null);206 }207 208 internal ComMethodDesc SetItem => _setItem;209 210 internal void EnsureSetItem(ComMethodDesc candidate)211 {212 Interlocked.CompareExchange(ref _setItem, candidate, null);213 }214 }215}216 