2 Copyright (C) 2009 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
25 using System.Collections.Generic;
26 using System.Configuration.Assemblies;
28 using IKVM.Reflection.Metadata;
30 namespace IKVM.Reflection.Reader
32 sealed class AssemblyReader : Assembly
34 private const int ContainsNoMetaData = 0x0001;
35 private readonly string location;
36 private readonly ModuleReader manifestModule;
37 private readonly Module[] externalModules;
39 internal AssemblyReader(string location, ModuleReader manifestModule)
40 : base(manifestModule.universe)
42 this.location = location;
43 this.manifestModule = manifestModule;
44 externalModules = new Module[manifestModule.File.records.Length];
47 public override string Location
49 get { return location; }
52 public override AssemblyName GetName()
54 return GetNameImpl(ref manifestModule.AssemblyTable.records[0]);
57 private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
59 AssemblyName name = new AssemblyName();
60 name.Name = manifestModule.GetString(rec.Name);
61 name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
62 if (rec.PublicKey != 0)
64 name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
68 name.SetPublicKey(Empty<byte>.Array);
72 name.Culture = manifestModule.GetString(rec.Culture);
78 name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
79 name.CodeBase = this.CodeBase;
80 name.RawFlags = (AssemblyNameFlags)rec.Flags;
84 public override Type[] GetTypes()
86 if (externalModules.Length == 0)
88 return manifestModule.GetTypes();
91 List<Type> list = new List<Type>();
92 foreach (Module module in GetModules(false))
94 list.AddRange(module.GetTypes());
96 return list.ToArray();
99 internal override Type FindType(TypeName typeName)
101 Type type = manifestModule.FindType(typeName);
102 for (int i = 0; type == null && i < externalModules.Length; i++)
104 if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
106 type = GetModule(i).FindType(typeName);
112 internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
114 Type type = manifestModule.FindTypeIgnoreCase(lowerCaseName);
115 for (int i = 0; type == null && i < externalModules.Length; i++)
117 if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
119 type = GetModule(i).FindTypeIgnoreCase(lowerCaseName);
125 public override string ImageRuntimeVersion
127 get { return manifestModule.__ImageRuntimeVersion; }
130 public override Module ManifestModule
132 get { return manifestModule; }
135 public override Module[] GetLoadedModules(bool getResourceModules)
137 List<Module> list = new List<Module>();
138 list.Add(manifestModule);
139 foreach (Module m in externalModules)
146 return list.ToArray();
149 public override Module[] GetModules(bool getResourceModules)
151 if (externalModules.Length == 0)
153 return new Module[] { manifestModule };
157 List<Module> list = new List<Module>();
158 list.Add(manifestModule);
159 for (int i = 0; i < manifestModule.File.records.Length; i++)
161 if (getResourceModules || (manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
163 list.Add(GetModule(i));
166 return list.ToArray();
170 public override Module GetModule(string name)
172 if (name.Equals(manifestModule.ScopeName, StringComparison.InvariantCultureIgnoreCase))
174 return manifestModule;
176 int index = GetModuleIndex(name);
179 return GetModule(index);
184 private int GetModuleIndex(string name)
186 for (int i = 0; i < manifestModule.File.records.Length; i++)
188 if (name.Equals(manifestModule.GetString(manifestModule.File.records[i].Name), StringComparison.InvariantCultureIgnoreCase))
196 private Module GetModule(int index)
198 if (externalModules[index] != null)
200 return externalModules[index];
202 // TODO add ModuleResolve event
203 string location = Path.Combine(Path.GetDirectoryName(this.location), manifestModule.GetString(manifestModule.File.records[index].Name));
204 return LoadModule(index, null, location);
207 private Module LoadModule(int index, byte[] rawModule, string location)
209 if ((manifestModule.File.records[index].Flags & ContainsNoMetaData) != 0)
211 return externalModules[index] = new ResourceModule(manifestModule, index, location);
215 if (rawModule == null)
217 rawModule = File.ReadAllBytes(location);
219 return externalModules[index] = new ModuleReader(this, manifestModule.universe, new MemoryStream(rawModule), location);
223 public override Module LoadModule(string moduleName, byte[] rawModule)
225 int index = GetModuleIndex(moduleName);
228 throw new ArgumentException();
230 if (externalModules[index] != null)
232 return externalModules[index];
234 return LoadModule(index, rawModule, null);
237 public override MethodInfo EntryPoint
239 get { return manifestModule.GetEntryPoint(); }
242 public override string[] GetManifestResourceNames()
244 return manifestModule.GetManifestResourceNames();
247 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
249 return manifestModule.GetManifestResourceInfo(resourceName);
252 public override Stream GetManifestResourceStream(string resourceName)
254 return manifestModule.GetManifestResourceStream(resourceName);
257 public override AssemblyName[] GetReferencedAssemblies()
259 return manifestModule.__GetReferencedAssemblies();
262 public override AssemblyNameFlags __AssemblyFlags
264 get { return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags; }
269 get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); }
272 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
274 return CustomAttributeData.GetCustomAttributesImpl(null, manifestModule, 0x20000001, attributeType) ?? CustomAttributeData.EmptyList;