Update to the latest IKVM.Reflection
[mono-project.git] / mcs / class / IKVM.Reflection / Reader / AssemblyReader.cs
blob2764e2d676cc916ceca391102464e08bd4326568
1 /*
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.
20 Jeroen Frijters
21 jeroen@frijters.net
24 using System;
25 using System.Collections.Generic;
26 using System.Configuration.Assemblies;
27 using System.IO;
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));
66 else
68 name.SetPublicKey(Empty<byte>.Array);
70 if (rec.Culture != 0)
72 name.Culture = manifestModule.GetString(rec.Culture);
74 else
76 name.Culture = "";
78 name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
79 name.CodeBase = this.CodeBase;
80 name.RawFlags = (AssemblyNameFlags)rec.Flags;
81 return name;
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);
109 return type;
112 public override string ImageRuntimeVersion
114 get { return manifestModule.__ImageRuntimeVersion; }
117 public override Module ManifestModule
119 get { return manifestModule; }
122 public override Module[] GetLoadedModules(bool getResourceModules)
124 List<Module> list = new List<Module>();
125 list.Add(manifestModule);
126 foreach (Module m in externalModules)
128 if (m != null)
130 list.Add(m);
133 return list.ToArray();
136 public override Module[] GetModules(bool getResourceModules)
138 if (externalModules.Length == 0)
140 return new Module[] { manifestModule };
142 else
144 List<Module> list = new List<Module>();
145 list.Add(manifestModule);
146 for (int i = 0; i < manifestModule.File.records.Length; i++)
148 if (getResourceModules || (manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
150 list.Add(GetModule(i));
153 return list.ToArray();
157 public override Module GetModule(string name)
159 if (name.Equals(manifestModule.ScopeName, StringComparison.InvariantCultureIgnoreCase))
161 return manifestModule;
163 int index = GetModuleIndex(name);
164 if (index != -1)
166 return GetModule(index);
168 return null;
171 private int GetModuleIndex(string name)
173 for (int i = 0; i < manifestModule.File.records.Length; i++)
175 if (name.Equals(manifestModule.GetString(manifestModule.File.records[i].Name), StringComparison.InvariantCultureIgnoreCase))
177 return i;
180 return -1;
183 private Module GetModule(int index)
185 if (externalModules[index] != null)
187 return externalModules[index];
189 // TODO add ModuleResolve event
190 string location = Path.Combine(Path.GetDirectoryName(this.location), manifestModule.GetString(manifestModule.File.records[index].Name));
191 return LoadModule(index, null, location);
194 private Module LoadModule(int index, byte[] rawModule, string location)
196 if ((manifestModule.File.records[index].Flags & ContainsNoMetaData) != 0)
198 return externalModules[index] = new ResourceModule(manifestModule, index, location);
200 else
202 if (rawModule == null)
204 rawModule = File.ReadAllBytes(location);
206 return externalModules[index] = new ModuleReader(this, manifestModule.universe, new MemoryStream(rawModule), location);
210 public override Module LoadModule(string moduleName, byte[] rawModule)
212 int index = GetModuleIndex(moduleName);
213 if (index == -1)
215 throw new ArgumentException();
217 if (externalModules[index] != null)
219 return externalModules[index];
221 return LoadModule(index, rawModule, null);
224 public override MethodInfo EntryPoint
226 get { return manifestModule.GetEntryPoint(); }
229 public override string[] GetManifestResourceNames()
231 return manifestModule.GetManifestResourceNames();
234 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
236 return manifestModule.GetManifestResourceInfo(resourceName);
239 public override Stream GetManifestResourceStream(string resourceName)
241 return manifestModule.GetManifestResourceStream(resourceName);
244 public override AssemblyName[] GetReferencedAssemblies()
246 return manifestModule.__GetReferencedAssemblies();
249 public override AssemblyNameFlags __AssemblyFlags
251 get { return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags; }
254 internal string Name
256 get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); }
259 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
261 return manifestModule.GetCustomAttributes(0x20000001, attributeType);