/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using System; using System.IO; namespace dnSpy.Debugger.DotNet.Metadata { /// /// Assembly name /// public sealed class DmdAssemblyName : IDmdAssemblyName { /// /// Gets/sets the simple name /// public string? Name { get; set; } /// /// Gets/sets the version /// public Version? Version { get; set; } /// /// Gets/sets the culture name /// public string? CultureName { get; set; } /// /// Gets/sets the flags /// public DmdAssemblyNameFlags RawFlags { get; set; } /// /// Gets/sets the flags. The content type and processor architecture bits are ignored, use instead /// public DmdAssemblyNameFlags Flags { get => RawFlags & ~(DmdAssemblyNameFlags.ContentType_Mask | DmdAssemblyNameFlags.PA_FullMask); set => RawFlags = (RawFlags & (DmdAssemblyNameFlags.ContentType_Mask | DmdAssemblyNameFlags.PA_FullMask)) | (value & ~(DmdAssemblyNameFlags.ContentType_Mask | DmdAssemblyNameFlags.PA_FullMask)); } /// /// Gets/sets the processor architecture /// public DmdProcessorArchitecture ProcessorArchitecture { get => (DmdProcessorArchitecture)((int)(RawFlags & DmdAssemblyNameFlags.PA_Mask) >> 4); set => RawFlags = (RawFlags & ~DmdAssemblyNameFlags.PA_FullMask) | ((DmdAssemblyNameFlags)((int)value << 4) & DmdAssemblyNameFlags.PA_Mask); } /// /// Gets/sets the content type /// public DmdAssemblyContentType ContentType { get => (DmdAssemblyContentType)((int)(RawFlags & DmdAssemblyNameFlags.ContentType_Mask) >> 9); set => RawFlags = (RawFlags & ~DmdAssemblyNameFlags.ContentType_Mask) | ((DmdAssemblyNameFlags)((int)value << 9) & DmdAssemblyNameFlags.ContentType_Mask); } /// /// Gets the public key /// /// public byte[]? GetPublicKey() => publicKey; byte[]? publicKey; /// /// Sets the public key /// /// Public key or null public void SetPublicKey(byte[]? publicKey) { this.publicKey = publicKey; if (publicKey is null) RawFlags &= ~DmdAssemblyNameFlags.PublicKey; else RawFlags |= DmdAssemblyNameFlags.PublicKey; } /// /// Gets the public key token /// /// public byte[]? GetPublicKeyToken() { if (publicKeyToken is null && publicKey is not null) { try { publicKeyToken = AssemblyHasher.CreatePublicKeyToken(publicKey); } catch (IOException) { } } return publicKeyToken; } byte[]? publicKeyToken; /// /// Sets the public key token /// /// Public key token public void SetPublicKeyToken(byte[] publicKeyToken) => this.publicKeyToken = publicKeyToken; /// /// Gets/sets the hash algorithm /// public DmdAssemblyHashAlgorithm HashAlgorithm { get; set; } /// /// Gets the full assembly name /// public string FullName => DmdAssemblyNameFormatter.Format(Name, Version, CultureName, GetPublicKeyToken(), RawFlags, isPublicKeyToken: true); /// /// Gets the full assembly name /// /// public override string ToString() => FullName; /// /// Constructor /// public DmdAssemblyName() { HashAlgorithm = DmdAssemblyHashAlgorithm.None; RawFlags = DmdAssemblyNameFlags.None; } DmdAssemblyName(DmdAssemblyName other) { Name = other.Name; Version = other.Version; CultureName = other.CultureName; RawFlags = other.RawFlags; HashAlgorithm = other.HashAlgorithm; publicKey = CloneArray(other.publicKey); publicKeyToken = CloneArray(other.publicKeyToken); } internal static T[]? CloneArray(T[]? array) { if (array is null) return null; var res = new T[array.Length]; Array.Copy(array, res, res.Length); return res; } /// /// Constructor /// /// Assembly name public DmdAssemblyName(string assemblyName) { if (assemblyName is null) throw new ArgumentNullException(nameof(assemblyName)); Impl.DmdTypeNameParser.ParseAssemblyName(assemblyName, out var name, out var version, out var cultureName, out var flags, out publicKey, out publicKeyToken, out var hashAlgorithm); Name = name; Version = version; CultureName = cultureName; RawFlags = flags; HashAlgorithm = hashAlgorithm; } /// /// Constructor /// /// Assembly name public DmdAssemblyName(IDmdAssemblyName name) { if (name is null) throw new ArgumentNullException(nameof(name)); Name = name.Name; Version = name.Version; CultureName = name.CultureName; RawFlags = name.RawFlags; publicKey = CloneArray(name.GetPublicKey()); publicKeyToken = CloneArray(name.GetPublicKeyToken()); HashAlgorithm = name.HashAlgorithm; } /// /// Creates a read only assembly name /// /// public DmdReadOnlyAssemblyName AsReadOnly() => new DmdReadOnlyAssemblyName(this); /// /// Clones this instance /// /// public DmdAssemblyName Clone() => new DmdAssemblyName(this); } }