2 // System.Reflection.Emit/AssemblyBuilder.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
11 using System.Reflection;
12 using System.Resources;
14 using System.Security.Policy;
15 using System.Runtime.Serialization;
16 using System.Globalization;
17 using System.Runtime.CompilerServices;
18 using System.Collections;
20 namespace System.Reflection.Emit {
22 internal struct MonoResource {
25 public string filename;
26 public ResourceAttributes attrs;
29 public sealed class AssemblyBuilder : Assembly {
30 private IntPtr dynamic_assembly;
31 private MethodInfo entry_point;
32 private ModuleBuilder[] modules;
35 private CustomAttributeBuilder[] cattrs;
36 private MonoResource[] resources;
42 PEFileKinds pekind = PEFileKinds.Dll;
44 internal Type corlib_object_type = typeof (System.Object);
45 internal Type corlib_value_type = typeof (System.ValueType);
46 internal Type corlib_enum_type = typeof (System.Enum);
47 private int[] table_indexes;
48 internal ArrayList methods;
49 Hashtable us_string_cache = new Hashtable ();
51 [MethodImplAttribute(MethodImplOptions.InternalCall)]
52 private static extern void basic_init (AssemblyBuilder ab);
54 internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access) {
60 internal int get_next_table_index (object obj, int table, bool inc) {
61 if (table_indexes == null) {
62 table_indexes = new int [64];
63 for (int i=0; i < 64; ++i)
64 table_indexes [i] = 1;
65 /* allow room for .<Module> in TypeDef table */
66 table_indexes [0x02] = 2;
68 // Console.WriteLine ("getindex for table "+table.ToString()+" got "+table_indexes [table].ToString());
70 if ((table == 0x06) && (methods != null))
72 return table_indexes [table]++;
74 return table_indexes [table];
77 public override string CodeBase {
83 public override MethodInfo EntryPoint {
89 public override string Location {
95 public void AddResourceFile (string name, string fileName)
97 AddResourceFile (name, fileName, ResourceAttributes.Public);
100 public void AddResourceFile (string name, string fileName, ResourceAttributes attribute)
102 if (resources != null) {
103 MonoResource[] new_r = new MonoResource [resources.Length + 1];
104 System.Array.Copy(resources, new_r, resources.Length);
107 resources = new MonoResource [1];
109 int p = resources.Length - 1;
110 resources [p].name = name;
111 resources [p].filename = fileName;
112 resources [p].attrs = attribute;
115 public void EmbedResourceFile (string name, string fileName)
117 EmbedResourceFile (name, fileName, ResourceAttributes.Public);
120 public void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
122 if (resources != null) {
123 MonoResource[] new_r = new MonoResource [resources.Length + 1];
124 System.Array.Copy(resources, new_r, resources.Length);
127 resources = new MonoResource [1];
129 int p = resources.Length - 1;
130 resources [p].name = name;
131 resources [p].attrs = attribute;
133 FileStream s = new FileStream (fileName, FileMode.Open, FileAccess.Read);
135 resources [p].data = new byte [len];
136 s.Read (resources [p].data, 0, (int)len);
143 public ModuleBuilder DefineDynamicModule (string name)
145 return DefineDynamicModule (name, name, false);
148 public ModuleBuilder DefineDynamicModule (string name, bool emitSymbolInfo)
150 return DefineDynamicModule (name, name, emitSymbolInfo);
153 public ModuleBuilder DefineDynamicModule(string name, string fileName)
155 return DefineDynamicModule (name, fileName, false);
158 public ModuleBuilder DefineDynamicModule (string name, string fileName,
161 ModuleBuilder r = new ModuleBuilder (this, name, fileName, emitSymbolInfo);
163 if (modules != null) {
164 ModuleBuilder[] new_modules = new ModuleBuilder [modules.Length + 1];
165 System.Array.Copy(modules, new_modules, modules.Length);
166 new_modules [modules.Length] = r;
167 modules = new_modules;
169 modules = new ModuleBuilder [1];
175 public IResourceWriter DefineResource (string name, string description, string fileName)
177 return DefineResource (name, description, fileName, ResourceAttributes.Public);
180 public IResourceWriter DefineResource (string name, string description,
181 string fileName, ResourceAttributes attribute)
186 public void DefineUnmanagedResource (byte[] resource)
190 public void DefineUnmanagedResource (string resourceFileName)
194 public void DefineVersionInfoResource ()
198 public void DefineVersionInfoResource (string product, string productVersion,
199 string company, string copyright, string trademark)
203 public ModuleBuilder GetDynamicModule (string name)
208 public override Type[] GetExportedTypes ()
213 public override FileStream GetFile (string name)
218 /*public virtual FileStream[] GetFiles() {
221 public override FileStream[] GetFiles(bool getResourceModules) {
225 /*public virtual ManifestResourceInfo GetManifestResourceInfo(string resourceName)
229 public virtual string[] GetManifestResourceNames() {
232 public virtual Stream GetManifestResourceStream(string name) {
235 public virtual Stream GetManifestResourceStream(Type type, string name) {
239 [MethodImplAttribute(MethodImplOptions.InternalCall)]
240 private static extern int getUSIndex (AssemblyBuilder ab, string str);
242 [MethodImplAttribute(MethodImplOptions.InternalCall)]
243 private static extern int getToken (AssemblyBuilder ab, MemberInfo member);
245 internal int GetToken (string str) {
246 if (us_string_cache.Contains (str))
247 return (int)us_string_cache [str];
248 int result = getUSIndex (this, str);
249 us_string_cache [str] = result;
253 internal int GetToken (MemberInfo member) {
254 return getToken (this, member);
257 [MethodImplAttribute(MethodImplOptions.InternalCall)]
258 private static extern int getDataChunk (AssemblyBuilder ab, byte[] buf, int offset);
260 public void Save (string assemblyFileName)
262 byte[] buf = new byte [65536];
267 assemblyFileName = String.Format ("{0}{1}{2}", dir, System.IO.Path.DirectorySeparatorChar, assemblyFileName);
270 file = new FileStream (assemblyFileName, FileMode.Create, FileAccess.Write);
273 while ((count = getDataChunk (this, buf, offset)) != 0) {
274 file.Write (buf, 0, count);
280 public void SetEntryPoint (MethodInfo entryMethod)
282 SetEntryPoint (entryMethod, PEFileKinds.ConsoleApplication);
285 public void SetEntryPoint (MethodInfo entryMethod, PEFileKinds fileKind)
287 entry_point = entryMethod;
291 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
292 string attrname = customBuilder.Ctor.ReflectedType.FullName;
295 if (attrname == "System.Reflection.AssemblyVersionAttribute") {
296 data = customBuilder.Data;
298 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
299 version = CustomAttributeBuilder.string_from_bytes (data, pos, len);
301 } else if (attrname == "System.Reflection.AssemblyKeyFileAttribute") {
302 data = customBuilder.Data;
304 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
305 keyfile = CustomAttributeBuilder.string_from_bytes (data, pos, len);
306 } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
307 data = customBuilder.Data;
309 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
310 culture = CustomAttributeBuilder.string_from_bytes (data, pos, len);
311 } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
312 data = customBuilder.Data;
314 algid = (uint)data [pos];
315 algid |= ((uint)data [pos + 1]) << 8;
316 algid |= ((uint)data [pos + 2]) << 16;
317 algid |= ((uint)data [pos + 3]) << 24;
318 } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
319 data = customBuilder.Data;
321 flags = (uint)data [pos];
322 flags |= ((uint)data [pos + 1]) << 8;
323 flags |= ((uint)data [pos + 2]) << 16;
324 flags |= ((uint)data [pos + 3]) << 24;
326 } else if (attrname == "System.Reflection.AssemblyDelaySignAttribute") {
327 data = customBuilder.Data;
329 delay_sign = data [2] != 0;
331 if (cattrs != null) {
332 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
333 cattrs.CopyTo (new_array, 0);
334 new_array [cattrs.Length] = customBuilder;
337 cattrs = new CustomAttributeBuilder [1];
338 cattrs [0] = customBuilder;
341 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
342 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
345 public void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
346 this.corlib_object_type = corlib_object_type;
347 this.corlib_value_type = corlib_value_type;
348 this.corlib_enum_type = corlib_enum_type;