context: /*
    Copyright (C) 2009 Jeroen Frijters
  
    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any damages
    arising from the use of this software.
  
    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:
  
    1. The origin of this software must not be misrepresented; you must not
       claim that you wrote the original software. If you use this software
       in a product, an acknowledgment in the product documentation would be
       appreciated but is not required.
    2. Altered source versions must be plainly marked as such, and must not be
       misrepresented as being the original software.
    3. This notice may not be removed or altered from any source distribution.
  
    Jeroen Frijters
    jeroen@frijters.net
    
  */
  using System;
  using System.Collections.Generic;
  using IKVM.Reflection.Metadata;
  using IKVM.Reflection.Reader;
  
  namespace IKVM.Reflection
  {
  	public sealed class RawModule : IDisposable
  	{
  		private readonly ModuleReader module;
  		private bool imported;
  
  		internal RawModule(ModuleReader module)
  		{
  			this.module = module;
  		}
  
  		public string Location
  		{
  			get { return module.FullyQualifiedName; }
  		}
  
  		public bool IsManifestModule
  		{
  			get { return module.Assembly != null; }
  		}
  
  		private void CheckManifestModule()
  		{
  			if (!IsManifestModule)
  			{
  				throw new BadImageFormatException("Module does not contain a manifest");
  			}
  		}
  
  		public AssemblyName GetAssemblyName()
  		{
  			CheckManifestModule();
  			return module.Assembly.GetName();
  		}
  
  		public AssemblyName[] GetReferencedAssemblies()
  		{
  			CheckManifestModule();
  			return module.Assembly.GetReferencedAssemblies();
  		}
  
  		public void Dispose()
  		{
  			if (!imported)
  			{
  				module.stream.Dispose();
  			}
  		}
  
  		internal Assembly ToAssembly()
  		{
  			if (imported)
  			{
  				throw new InvalidOperationException();
  			}
  			imported = true;
  			return module.Assembly;
  		}
  	}
  
  	public abstract class Module : ICustomAttributeProvider
  	{
  		internal readonly Universe universe;
  		internal readonly ModuleTable ModuleTable = new ModuleTable();
  		internal readonly TypeRefTable TypeRef = new TypeRefTable();
  		internal readonly TypeDefTable TypeDef = new TypeDefTable();
  		internal readonly FieldTable Field = new FieldTable();
  		internal readonly MemberRefTable MemberRef = new MemberRefTable();
  		internal readonly ConstantTable Constant = new ConstantTable();
  		internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable();
  		internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable();
  		internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable();
  		internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable();
  		internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable();
  		internal readonly ParamTable Param = new ParamTable();
  		internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable();
  		internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable();
  		internal readonly EventMapTable EventMap = new EventMapTable();
  		internal readonly EventTable Event = new EventTable();
  		internal readonly PropertyMapTable PropertyMap = new PropertyMapTable();
  		internal readonly PropertyTable Property = new PropertyTable();
  		internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable();
  		internal readonly MethodImplTable MethodImpl = new MethodImplTable();
  		internal readonly ModuleRefTable ModuleRef = new ModuleRefTable();
  		internal readonly TypeSpecTable TypeSpec = new TypeSpecTable();
  		internal readonly ImplMapTable ImplMap = new ImplMapTable();
  		internal readonly FieldRVATable FieldRVA = new FieldRVATable();
  		internal readonly AssemblyTable AssemblyTable = new AssemblyTable();
  		internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable();
  		internal readonly MethodDefTable MethodDef = new MethodDefTable();
  		internal readonly NestedClassTable NestedClass = new NestedClassTable();
  		internal readonly FileTable File = new FileTable();
  		internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable();
  		internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable();
  		internal readonly GenericParamTable GenericParam = new GenericParamTable();
  		internal readonly MethodSpecTable MethodSpec = new MethodSpecTable();
  		internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable();
  
  		internal Module(Universe universe)
  		{
  			this.universe = universe;
  		}
  
  		internal Table[] GetTables()
  		{
  			Table[] tables = new Table[64];
  			tables[ModuleTable.Index] = ModuleTable;
  			tables[TypeRefTable.Index] = TypeRef;
  			tables[TypeDefTable.Index] = TypeDef;
  			tables[FieldTable.Index] = Field;
  			tables[MemberRefTable.Index] = MemberRef;
  			tables[ConstantTable.Index] = Constant;
  			tables[CustomAttributeTable.Index] = CustomAttribute;
  			tables[FieldMarshalTable.Index] = FieldMarshal;
  			tables[DeclSecurityTable.Index] = DeclSecurity;
  			tables[ClassLayoutTable.Index] = ClassLayout;
  			tables[FieldLayoutTable.Index] = FieldLayout;
  			tables[ParamTable.Index] = Param;
  			tables[InterfaceImplTable.Index] = InterfaceImpl;
  			tables[StandAloneSigTable.Index] = StandAloneSig;
  			tables[EventMapTable.Index] = EventMap;
  			tables[EventTable.Index] = Event;
  			tables[PropertyMapTable.Index] = PropertyMap;
  			tables[PropertyTable.Index] = Property;
  			tables[MethodSemanticsTable.Index] = MethodSemantics;
  			tables[MethodImplTable.Index] = MethodImpl;
  			tables[ModuleRefTable.Index] = ModuleRef;
  			tables[TypeSpecTable.Index] = TypeSpec;
  			tables[ImplMapTable.Index] = ImplMap;
  			tables[FieldRVATable.Index] = FieldRVA;
  			tables[AssemblyTable.Index] = AssemblyTable;
  			tables[AssemblyRefTable.Index] = AssemblyRef;
  			tables[MethodDefTable.Index] = MethodDef;
  			tables[NestedClassTable.Index] = NestedClass;
  			tables[FileTable.Index] = File;
  			tables[ExportedTypeTable.Index] = ExportedType;
  			tables[ManifestResourceTable.Index] = ManifestResource;
  			tables[GenericParamTable.Index] = GenericParam;
  			tables[MethodSpecTable.Index] = MethodSpec;
  			tables[GenericParamConstraintTable.Index] = GenericParamConstraint;
  			return tables;
  		}
  
  		public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length)
  		{
  			throw new NotSupportedException();
  		}
  
  		public virtual long __RelativeVirtualAddressToFileOffset(int rva)
  		{
  			throw new NotSupportedException();
  		}
  
  		public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
  		{
  			throw new NotSupportedException();
  		}
  
  		public virtual int __Subsystem
  		{
  			get { throw new NotSupportedException(); }
  		}
  
  		public FieldInfo GetField(string name)
  		{
  			return IsResource() ? null : GetModuleType().GetField(name);
  		}
  
  		public FieldInfo GetField(string name, BindingFlags bindingFlags)
  		{
  			return IsResource() ? null : GetModuleType().GetField(name, bindingFlags);
  		}
  
  		public FieldInfo[] GetFields()
  		{
  			return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields();
  		}
  
  		public FieldInfo[] GetFields(BindingFlags bindingFlags)
  		{
  			return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields(bindingFlags);
  		}
  
  		public MethodInfo GetMethod(string name)
  		{
  			return IsResource() ? null : GetModuleType().GetMethod(name);
  		}
  
  		public MethodInfo GetMethod(string name, Type[] types)
  		{
  			return IsResource() ? null : GetModuleType().GetMethod(name, types);
  		}
  
  		public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
  		{
  			return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr, binder, callConv, types, modifiers);
  		}
  
  		public MethodInfo[] GetMethods()
  		{
  			return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods();
  		}
  
  		public MethodInfo[] GetMethods(BindingFlags bindingFlags)
  		{
  			return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods(bindingFlags);
  		}
  
  		public ConstructorInfo __ModuleInitializer
  		{
  			get { return IsResource() ? null : GetModuleType().TypeInitializer; }
  		}
  
  		public byte[] ResolveSignature(int metadataToken)
  		{
  			ModuleReader rdr = this as ModuleReader;
  			if (rdr != null)
  			{
  
gt: 				ByteReader br = rdr.ResolveSignature(metadataToken);