[corlib] Update public api
[mono.git] / mcs / class / corlib / System.Reflection / Assembly.cs
index 5401c0b7bcafff392dc649c0737d0a32a8925e9c..0bba65f4693a630934df471360618a9d26b4b2f7 100644 (file)
@@ -39,6 +39,9 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Collections.Generic;
 using System.Configuration.Assemblies;
+using System.Threading;
+using System.Text;
+using System.Diagnostics.Contracts;
 
 using Mono.Security;
 
@@ -58,6 +61,31 @@ namespace System.Reflection {
                        public event ModuleResolveEventHandler ModuleResolve;
                }
 
+               internal class UnmanagedMemoryStreamForModule : UnmanagedMemoryStream
+               {
+                       Module module;
+
+                       public unsafe UnmanagedMemoryStreamForModule (byte* pointer, long length, Module module)
+                               : base (pointer, length)
+                       {
+                               this.module = module;
+                       }
+
+                       protected override void Dispose (bool disposing)
+                       {
+                               if (_isOpen) {
+                                       /* 
+                                        * The returned pointer points inside metadata, so
+                                        * we have to increase the refcount of the module, and decrease
+                                        * it when the stream is finalized.
+                                        */
+                                       module = null;
+                               }
+
+                               base.Dispose (disposing);
+                       }
+               }
+
                // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
 #pragma warning disable 649
                private IntPtr _mono_assembly;
@@ -201,13 +229,9 @@ namespace System.Reflection {
                        }
                }
 
-               [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
                public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
                {
-                       if (info == null)
-                               throw new ArgumentNullException ("info");
-
-                       UnitySerializationHolder.GetAssemblyData (this, info, context);
+                       throw new NotImplementedException ();
                }
 
                public virtual bool IsDefined (Type attributeType, bool inherit)
@@ -308,33 +332,66 @@ namespace System.Reflection {
                        else {
                                UnmanagedMemoryStream stream;
                                unsafe {
-                                       stream = new UnmanagedMemoryStream ((byte*) data, size);
+                                       stream = new UnmanagedMemoryStreamForModule ((byte*) data, size, module);
                                }
-                               /* 
-                                * The returned pointer points inside metadata, so
-                                * we have to increase the refcount of the module, and decrease
-                                * it when the stream is finalized.
-                                */
-                               stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
                                return stream;
                        }
                }
 
                public virtual Stream GetManifestResourceStream (Type type, String name)
                {
-                       string ns;
-                       if (type != null) {
-                               ns = type.Namespace;
-                       } else {
+                       StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+                       return GetManifestResourceStream(type, name, false, ref stackMark);
+               }
+
+               internal Stream GetManifestResourceStream (Type type, String name, bool skipSecurityCheck, ref StackCrawlMark stackMark)
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       if (type == null) {
                                if (name == null)
-                                       throw new ArgumentNullException ("type");
-                               ns = null;
+                                               throw new ArgumentNullException ("type");
+                       } else {
+                               String nameSpace = type.Namespace;
+                               if (nameSpace != null) {
+                                       sb.Append (nameSpace);
+                                       if (name != null)
+                                               sb.Append (Type.Delimiter);
+                               }
                        }
 
-                       if (ns == null || ns.Length == 0)
-                               return GetManifestResourceStream (name);
-                       else
-                               return GetManifestResourceStream (ns + "." + name);
+                       if (name != null)
+                               sb.Append(name);
+
+                       return GetManifestResourceStream (sb.ToString());
+               }
+
+               internal unsafe Stream GetManifestResourceStream(String name, ref StackCrawlMark stackMark, bool skipSecurityCheck)
+               {
+                       return GetManifestResourceStream (null, name, skipSecurityCheck, ref stackMark);
+               }
+
+               internal String GetSimpleName()
+               {
+                       AssemblyName aname = GetName (true);
+                       return aname.Name;
+               }
+
+               internal byte[] GetPublicKey()
+               {
+                       AssemblyName aname = GetName (true);
+                       return aname.GetPublicKey ();
+               }
+
+               internal Version GetVersion()
+               {
+                       AssemblyName aname = GetName (true);
+                       return aname.Version;
+               }
+
+               private AssemblyNameFlags GetFlags()
+               {
+                       AssemblyName aname = GetName (true);
+                       return aname.Flags;
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
@@ -420,40 +477,53 @@ namespace System.Reflection {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public static extern Assembly GetEntryAssembly();
 
-               internal Assembly GetSatelliteAssemblyNoThrow (CultureInfo culture, Version version)
+               internal Assembly GetSatelliteAssembly (CultureInfo culture, Version version, bool throwOnError)
                {
-                       return GetSatelliteAssembly (culture, version, false);
+                       if (culture == null)
+                               throw new ArgumentNullException("culture");
+                       Contract.EndContractBlock();
+
+                       StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+                       String name = GetSimpleName() + ".resources";
+                       return InternalGetSatelliteAssembly(name, culture, version, true, ref stackMark);
                }
 
-               internal Assembly GetSatelliteAssembly (CultureInfo culture, Version version, bool throwOnError)
+               internal RuntimeAssembly InternalGetSatelliteAssembly (String name, CultureInfo culture, Version version, bool throwOnFileNotFound, ref StackCrawlMark stackMark)
                {
-                       if (culture == null)
-                               throw new ArgumentException ("culture");
+                       AssemblyName an = new AssemblyName ();
 
-                       AssemblyName aname = GetName (true);
-                       if (version != null)
-                               aname.Version = version;
+                       an.SetPublicKey (GetPublicKey ());
+                       an.Flags = GetFlags () | AssemblyNameFlags.PublicKey;
+
+                       if (version == null)
+                               an.Version = GetVersion ();
+                       else
+                               an.Version = version;
+
+                       an.CultureInfo = culture;
+                       an.Name = name;
 
-                       aname.CultureInfo = culture;
-                       aname.Name = aname.Name + ".resources";
                        Assembly assembly;
 
                        try {
-                               assembly = AppDomain.CurrentDomain.LoadSatellite (aname, false);
+                               assembly = AppDomain.CurrentDomain.LoadSatellite (an, false);
                                if (assembly != null)
-                                       return assembly;
+                                       return (RuntimeAssembly)assembly;
                        } catch (FileNotFoundException) {
                                assembly = null;
                                // ignore
                        }
 
+                       if (String.IsNullOrEmpty (Location))
+                               return null;
+
                        // Try the assembly directory
                        string location = Path.GetDirectoryName (Location);
-                       string fullName = Path.Combine (location, Path.Combine (culture.Name, aname.Name + ".dll"));
-                       if (!throwOnError && !File.Exists (fullName))
+                       string fullName = Path.Combine (location, Path.Combine (culture.Name, an.Name + ".dll"));
+                       if (!throwOnFileNotFound && !File.Exists (fullName))
                                return null;
 
-                       return LoadFrom (fullName);
+                       return (RuntimeAssembly)LoadFrom (fullName);
                }
 
 #if !MOBILE
@@ -701,7 +771,7 @@ namespace System.Reflection {
                                throw new ArgumentNullException ("resourceName");
                        if (resourceName.Length == 0)
                                throw new ArgumentException ("String cannot have zero length.");
-                       ManifestResourceInfo result = new ManifestResourceInfo ();
+                       ManifestResourceInfo result = new ManifestResourceInfo (null, null, 0);
                        bool found = GetManifestResourceInfoInternal (resourceName, result);
                        if (found)
                                return result;
@@ -709,21 +779,6 @@ namespace System.Reflection {
                                return null;
                }
 
-               private class ResourceCloseHandler {
-#pragma warning disable 169, 414
-                       Module module;
-#pragma warning restore 169, 414                       
-
-                       public ResourceCloseHandler (Module module) {
-                               this.module = module;
-                       }
-
-                       public void OnClose (object sender, EventArgs e) {
-                               // The module dtor will take care of things
-                               module = null;
-                       }
-               }
-
                [MonoTODO ("Currently it always returns zero")]
                [ComVisible (false)]
                public