/*
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);
}
}