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 string FullName
54 get { return GetName().FullName; }
57 public override AssemblyName GetName()
59 return GetNameImpl(ref manifestModule.AssemblyTable.records[0]);
62 private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
64 AssemblyName name = new AssemblyName();
65 name.Name = manifestModule.GetString(rec.Name);
66 name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
67 if (rec.PublicKey != 0)
69 name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
73 name.SetPublicKey(Empty<byte>.Array);
77 name.CultureInfo = new System.Globalization.CultureInfo(manifestModule.GetString(rec.Culture));
81 name.CultureInfo = System.Globalization.CultureInfo.InvariantCulture;
83 name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
84 name.CodeBase = this.CodeBase;
85 name.Flags = (AssemblyNameFlags)rec.Flags;
89 public override Type[] GetTypes()
91 if (externalModules.Length == 0)
93 return manifestModule.GetTypes();
96 List<Type> list = new List<Type>();
97 foreach (Module module in GetModules(false))
99 list.AddRange(module.GetTypes());
101 return list.ToArray();
104 internal override Type FindType(TypeName typeName)
106 Type type = manifestModule.FindType(typeName);
107 for (int i = 0; type == null && i < externalModules.Length; i++)
109 if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
111 type = GetModule(i).FindType(typeName);
117 public override string ImageRuntimeVersion
119 get { return manifestModule.ImageRuntimeVersion; }
122 public override Module ManifestModule
124 get { return manifestModule; }
127 public override Module[] GetLoadedModules(bool getResourceModules)
129 List<Module> list = new List<Module>();
130 list.Add(manifestModule);
131 foreach (Module m in externalModules)
138 return list.ToArray();
141 public override Module[] GetModules(bool getResourceModules)
143 if (externalModules.Length == 0)
145 return new Module[] { manifestModule };
149 List<Module> list = new List<Module>();
150 list.Add(manifestModule);
151 for (int i = 0; i < manifestModule.File.records.Length; i++)
153 if (getResourceModules || (manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
155 list.Add(GetModule(i));
158 return list.ToArray();
162 public override Module GetModule(string name)
164 if (name.Equals(manifestModule.ScopeName, StringComparison.InvariantCultureIgnoreCase))
166 return manifestModule;
168 int index = GetModuleIndex(name);
171 return GetModule(index);
176 private int GetModuleIndex(string name)
178 for (int i = 0; i < manifestModule.File.records.Length; i++)
180 if (name.Equals(manifestModule.GetString(manifestModule.File.records[i].Name), StringComparison.InvariantCultureIgnoreCase))
188 private Module GetModule(int index)
190 if (externalModules[index] != null)
192 return externalModules[index];
194 // TODO add ModuleResolve event
195 string location = Path.Combine(Path.GetDirectoryName(this.location), manifestModule.GetString(manifestModule.File.records[index].Name));
196 return LoadModule(index, null, location);
199 private Module LoadModule(int index, byte[] rawModule, string location)
201 if ((manifestModule.File.records[index].Flags & ContainsNoMetaData) != 0)
203 return externalModules[index] = new ResourceModule(manifestModule, index, location);
207 if (rawModule == null)
209 rawModule = File.ReadAllBytes(location);
211 return externalModules[index] = new ModuleReader(this, manifestModule.universe, new MemoryStream(rawModule), location);
215 public override Module LoadModule(string moduleName, byte[] rawModule)
217 int index = GetModuleIndex(moduleName);
220 throw new ArgumentException();
222 if (externalModules[index] != null)
224 return externalModules[index];
226 return LoadModule(index, rawModule, null);
229 public override MethodInfo EntryPoint
231 get { return manifestModule.GetEntryPoint(); }
234 public override string[] GetManifestResourceNames()
236 return manifestModule.GetManifestResourceNames();
239 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
241 return manifestModule.GetManifestResourceInfo(resourceName);
244 public override Stream GetManifestResourceStream(string resourceName)
246 return manifestModule.GetManifestResourceStream(resourceName);
249 public override AssemblyName[] GetReferencedAssemblies()
251 return manifestModule.__GetReferencedAssemblies();
254 public override AssemblyNameFlags __AssemblyFlags
256 get { return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags; }
259 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
261 return manifestModule.GetCustomAttributes(0x20000001, attributeType);