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 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
)
133 return list
.ToArray();
136 public override Module
[] GetModules(bool getResourceModules
)
138 if (externalModules
.Length
== 0)
140 return new Module
[] { manifestModule }
;
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
);
166 return GetModule(index
);
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
))
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
);
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
);
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; }
256 get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); }
259 internal override IList
<CustomAttributeData
> GetCustomAttributesData(Type attributeType
)
261 return manifestModule
.GetCustomAttributes(0x20000001, attributeType
);