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.Collections.Generic;
21 using System.Globalization;
22 using System.Security;
23 using ComTypes = System.Runtime.InteropServices.ComTypes;
26 namespace System.Dynamic {
28 namespace Microsoft.Scripting {
31 internal sealed class ComTypeLibDesc {
33 // typically typelibs contain very small number of coclasses
34 // so we will just use the linked list as it performs better
35 // on small number of entities
36 LinkedList<ComTypeClassDesc> _classes;
37 Dictionary<string, ComTypeEnumDesc> _enums;
40 private static readonly Dictionary<Guid, ComTypeLibDesc> _CachedTypeLibDesc = new Dictionary<Guid, ComTypeLibDesc>();
42 private ComTypeLibDesc() {
43 _enums = new Dictionary<string, ComTypeEnumDesc>();
44 _classes = new LinkedList<ComTypeClassDesc>();
47 public override string ToString() {
48 return String.Format(CultureInfo.CurrentCulture, "<type library {0}>", _typeLibName);
52 internal static ComTypeLibDesc GetFromTypeLib(ComTypes.ITypeLib typeLib) {
53 // check whether we have already loaded this type library
54 ComTypes.TYPELIBATTR typeLibAttr = ComRuntimeHelpers.GetTypeAttrForTypeLib(typeLib);
55 ComTypeLibDesc typeLibDesc;
56 lock (_CachedTypeLibDesc) {
57 if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc)) {
62 typeLibDesc = new ComTypeLibDesc();
64 typeLibDesc._typeLibName = ComRuntimeHelpers.GetNameOfLib(typeLib);
66 int countTypes = typeLib.GetTypeInfoCount();
67 for (int i = 0; i < countTypes; i++) {
68 ComTypes.TYPEKIND typeKind;
69 typeLib.GetTypeInfoType(i, out typeKind);
71 ComTypes.ITypeInfo typeInfo;
72 if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS) {
73 typeLib.GetTypeInfo(i, out typeInfo);
74 ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo);
75 typeLibDesc._classes.AddLast(classDesc);
76 } else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM) {
77 typeLib.GetTypeInfo(i, out typeInfo);
78 ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo);
79 typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc);
83 // cache the typelib using the guid as the dictionary key
84 lock (_CachedTypeLibDesc) {
85 //check if we are late and somebody already added the key.
86 ComTypeLibDesc curLibDesc;
87 if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out curLibDesc)) {
91 _CachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc);
97 internal ComTypeClassDesc GetCoClassForInterface(string itfName) {
98 foreach (ComTypeClassDesc coclass in _classes) {
99 if (coclass.Implements(itfName, false)) {