Xamarin Public Jenkins (auto-signing) ef583813eb Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
2019-07-26 19:53:28 +00:00

129 lines
4.3 KiB
C#

using Mono;
using System.Configuration.Assemblies;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Reflection
{
[StructLayout (LayoutKind.Sequential)]
partial class AssemblyName
{
public AssemblyName (string assemblyName)
{
if (assemblyName == null)
throw new ArgumentNullException (nameof (assemblyName));
if (assemblyName.Length == 0 || assemblyName [0] == '\0')
throw new ArgumentException (SR.Format_StringZeroLength);
using (var name = RuntimeMarshal.MarshalString (assemblyName)) {
// TODO: Should use CoreRT AssemblyNameParser
if (!ParseAssemblyName (name.Value, out var nativeName, out var isVersionDefined, out var isTokenDefined))
throw new FileLoadException ("The assembly name is invalid.");
try {
unsafe {
FillName (&nativeName, null, isVersionDefined, false, isTokenDefined);
}
} finally {
RuntimeMarshal.FreeAssemblyName (ref nativeName, false);
}
}
}
unsafe byte [] ComputePublicKeyToken ()
{
if (_publicKey == null || _publicKey.Length == 0)
return Array.Empty<byte>();
var token = new byte [8];
fixed (byte* pkt = token)
fixed (byte *pk = _publicKey)
get_public_token (pkt, pk, _publicKey.Length);
return token;
}
internal static AssemblyName Create (Assembly assembly, bool fillCodebase)
{
AssemblyName aname = new AssemblyName ();
unsafe {
MonoAssemblyName *native = GetNativeName (assembly.MonoAssembly);
aname.FillName (native, fillCodebase ? assembly.CodeBase : null, true, true, true);
}
return aname;
}
internal unsafe void FillName (MonoAssemblyName *native, string codeBase, bool addVersion, bool addPublickey, bool defaultToken)
{
_name = RuntimeMarshal.PtrToUtf8String (native->name);
_flags = (AssemblyNameFlags) native->flags;
_hashAlgorithm = (AssemblyHashAlgorithm) native->hash_alg;
_versionCompatibility = AssemblyVersionCompatibility.SameMachine;
if (addVersion) {
var build = native->build == 65535 ? -1 : native->build;
var revision = native->revision == 65535 ? -1 : native->revision;
if (build == -1)
_version = new Version (native->major, native->minor);
else if (revision == -1)
_version = new Version (native->major, native->minor, build);
else
_version = new Version (native->major, native->minor, build, revision);
}
_codeBase = codeBase;
if (native->culture != IntPtr.Zero)
_cultureInfo = CultureInfo.GetCultureInfo (RuntimeMarshal.PtrToUtf8String (native->culture));
if (native->public_key != IntPtr.Zero) {
_publicKey = RuntimeMarshal.DecodeBlobArray (native->public_key);
_flags |= AssemblyNameFlags.PublicKey;
} else if (addPublickey) {
_publicKey = Array.Empty<byte> ();
_flags |= AssemblyNameFlags.PublicKey;
}
// MonoAssemblyName keeps the public key token as an hexadecimal string
if (native->public_key_token [0] != 0) {
var keyToken = new byte [8];
for (int i = 0, j = 0; i < 8; ++i) {
keyToken [i] = (byte) (RuntimeMarshal.AsciHexDigitValue (native->public_key_token [j++]) << 4);
keyToken [i] |= (byte) RuntimeMarshal.AsciHexDigitValue (native->public_key_token [j++]);
}
_publicKeyToken = keyToken;
} else if (defaultToken) {
_publicKeyToken = Array.Empty<byte> ();
}
}
static AssemblyName GetFileInformationCore (string assemblyFile)
{
unsafe {
Assembly.InternalGetAssemblyName (Path.GetFullPath (assemblyFile), out var nativeName, out var codebase);
var aname = new AssemblyName ();
try {
aname.FillName (&nativeName, codebase, true, false, true);
return aname;
} finally {
RuntimeMarshal.FreeAssemblyName (ref nativeName, false);
}
}
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
static extern unsafe void get_public_token (byte* token, byte* pubkey, int len);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
static extern unsafe MonoAssemblyName* GetNativeName (IntPtr assemblyPtr);
[MethodImpl (MethodImplOptions.InternalCall)]
static extern bool ParseAssemblyName (IntPtr name, out MonoAssemblyName aname, out bool is_version_definited, out bool is_token_defined);
}
}