Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.Reflection / AssemblyName.cs
index d0cd7dda64d0e872e7a9956618a12ab8304587d1..c1114225767e564c7cb97f2774dbb07ca3e6f485 100644 (file)
@@ -53,8 +53,12 @@ namespace System.Reflection {
        [ComDefaultInterfaceAttribute (typeof (_AssemblyName))]
        [Serializable]
        [ClassInterfaceAttribute (ClassInterfaceType.None)]
+       [StructLayout (LayoutKind.Sequential)]
+#if MOBILE
+       public sealed class AssemblyName  : ICloneable, ISerializable, IDeserializationCallback {
+#else
        public sealed class AssemblyName  : ICloneable, ISerializable, IDeserializationCallback, _AssemblyName {
-
+#endif
 #pragma warning disable 169
                #region Synch with object-internals.h
                string name;
@@ -71,7 +75,10 @@ namespace System.Reflection {
                ProcessorArchitecture processor_architecture = ProcessorArchitecture.None;
                #endregion
 #pragma warning restore 169            
-               
+
+#if NET_4_5
+               AssemblyContentType contentType;
+#endif         
                public AssemblyName ()
                {
                        // defaults
@@ -150,7 +157,10 @@ namespace System.Reflection {
                                if (name == null)
                                        return string.Empty;
                                StringBuilder fname = new StringBuilder ();
-                               fname.Append (name);
+                               if (Char.IsWhiteSpace (name [0]))
+                                       fname.Append ("\"" + name + "\"");
+                               else
+                                       fname.Append (name);
                                if (Version != null) {
                                        fname.Append (", Version=");
                                        fname.Append (Version.ToString ());
@@ -228,18 +238,17 @@ namespace System.Reflection {
                {
                        if (keyToken != null)
                                return keyToken;
-                       else if (publicKey == null)
+                       if (publicKey == null)
                                return null;
-                       else {
+
                                if (publicKey.Length == 0)
-                                       return new byte [0];
+                                       return EmptyArray<byte>.Value;
 
                                if (!IsPublicKeyValid)
                                        throw new  SecurityException ("The public key is not valid.");
 
                                keyToken = ComputePublicKeyToken ();
                                return keyToken;
-                       }
                }
 
                private bool IsPublicKeyValid {
@@ -257,21 +266,29 @@ namespace System.Reflection {
                                switch (publicKey [0]) {
                                case 0x00: // public key inside a header
                                        if (publicKey.Length > 12 && publicKey [12] == 0x06) {
+#if MOBILE
+                                               return true;
+#else
                                                try {
                                                        CryptoConvert.FromCapiPublicKeyBlob (
                                                                publicKey, 12);
                                                        return true;
                                                } catch (CryptographicException) {
                                                }
+#endif
                                        }
                                        break;
                                case 0x06: // public key
+#if MOBILE
+                                       return true;
+#else
                                        try {
                                                CryptoConvert.FromCapiPublicKeyBlob (publicKey);
                                                return true;
                                        } catch (CryptographicException) {
                                        }
-                                       break;
+                                       break;                                  
+#endif
                                case 0x07: // private key
                                        break;
                                }
@@ -289,7 +306,7 @@ namespace System.Reflection {
                                return null;
 
                        if (publicKey.Length == 0)
-                               return new byte [0];
+                               return EmptyArray<byte>.Value;
 
                        if (!IsPublicKeyValid)
                                throw new  SecurityException ("The public key is not valid.");
@@ -297,27 +314,28 @@ namespace System.Reflection {
                        return ComputePublicKeyToken ();
                }
 
-               private byte [] ComputePublicKeyToken ()
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern unsafe static void get_public_token (byte* token, byte* pubkey, int len);
+
+               private unsafe byte [] ComputePublicKeyToken ()
                {
-                       HashAlgorithm ha = SHA1.Create ();
-                       byte [] hash = ha.ComputeHash (publicKey);
-                       // we need the last 8 bytes in reverse order
                        byte [] token = new byte [8];
-                       Array.Copy (hash, (hash.Length - 8), token, 0, 8);
-                       Array.Reverse (token, 0, 8);
+                       fixed (byte* pkt = token)
+                       fixed (byte *pk = publicKey)
+                               get_public_token (pkt, pk, publicKey.Length);
                        return token;
                }
 
-               [MonoTODO]
                public static bool ReferenceMatchesDefinition (AssemblyName reference, AssemblyName definition)
                {
                        if (reference == null)
                                throw new ArgumentNullException ("reference");
                        if (definition == null)
                                throw new ArgumentNullException ("definition");
-                       if (reference.Name != definition.Name)
-                               return false;
-                       throw new NotImplementedException ();
+                       
+                       // we only compare the simple assembly name to be consistent with MS .NET,
+                       // which is the result of a bug in their implementation (see https://connect.microsoft.com/VisualStudio/feedback/details/752902)
+                       return string.Equals (reference.Name, definition.Name, StringComparison.OrdinalIgnoreCase);
                }
 
                public void SetPublicKey (byte[] publicKey) 
@@ -371,6 +389,7 @@ namespace System.Reflection {
                        an.publicKey = publicKey;
                        an.keyToken = keyToken;
                        an.versioncompat = versioncompat;
+                       an.processor_architecture = processor_architecture;
                        return an;
                }
 
@@ -389,7 +408,7 @@ namespace System.Reflection {
                        return aname;
                }
 
-#if NET_1_1
+#if !MOBILE
                void _AssemblyName.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
                {
                        throw new NotImplementedException ();
@@ -411,5 +430,27 @@ namespace System.Reflection {
                        throw new NotImplementedException ();
                }
 #endif
+
+#if NET_4_5
+               public string CultureName {
+                       get {
+                               if (cultureinfo == null)
+                                       return null;
+                               if (cultureinfo.LCID == CultureInfo.InvariantCulture.LCID)
+                                       return "neutral";
+                               return cultureinfo.Name;
+                       }
+               }
+
+               [ComVisibleAttribute(false)]
+               public AssemblyContentType ContentType {
+                       get {
+                               return contentType;
+                       }
+                       set {
+                               contentType = value;
+                       }
+               }
+#endif
        }
 }