// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; namespace dnlib.DotNet.Resources { /// /// Resource element set /// public sealed class ResourceElementSet { internal const string DeserializingResourceReaderTypeNameRegex = @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions"; internal const string ResourceReaderTypeNameRegex = @"^System\.Resources\.ResourceReader,\s*mscorlib"; readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); /// /// The ResourceReader type name used by this set /// public string ResourceReaderTypeName { get; } /// /// The ResourceSet type name used by this set /// public string ResourceSetTypeName { get; } /// /// The type of resource reader used to read this set /// public ResourceReaderType ReaderType { get; } /// /// Format version of the resource set /// public int FormatVersion { get; internal set; } /// /// Creates a new instance /// /// The ResourceReader type name to use /// The ResourceSet type name to use /// internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeName, ResourceReaderType readerType) { ResourceReaderTypeName = resourceReaderTypeName; ResourceSetTypeName = resourceSetTypeName; ReaderType = readerType; } /// /// Gets the number of elements in the set /// public int Count => dict.Count; /// /// Gets all resource elements /// public IEnumerable ResourceElements => dict.Values; /// /// Adds a new resource to the set, overwriting any existing resource /// /// public void Add(ResourceElement elem) => dict[elem.Name] = elem; /// /// Creates a new instance for a DeserializingResourceReader /// /// Version of System.Resources.Extensions assembly to use /// Resource format version, the default is 2 public static ResourceElementSet CreateForDeserializingResourceReader(Version extensionAssemblyVersion, int formatVersion = 2) { var extensionAssemblyFullName = $"System.Resources.Extensions, Version={extensionAssemblyVersion.ToString(4)}, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"; return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}", ResourceReaderType.DeserializingResourceReader) { FormatVersion = formatVersion }; } /// /// Creates a new instance for a ResourceReader /// /// Module in which the set will reside /// /// Resource format version, the default is 2 public static ResourceElementSet CreateForResourceReader(ModuleDef module, int formatVersion = 2) { string mscorlibFullName; if (module.CorLibTypes.AssemblyRef.Name == "mscorlib") { // Use mscorlib reference found in module. mscorlibFullName = module.CorLibTypes.AssemblyRef.FullName; } else { // Use a reference to 4.0.0.0 mscorlib for compatibility with .NET Core, .NET 5, and later. mscorlibFullName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader) { FormatVersion = formatVersion }; } /// /// Creates a new instance for a ResourceReader /// /// mscorlib assembly version /// Resource format version, the default is 2 public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion, int formatVersion = 2) { return new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader) { FormatVersion = formatVersion }; } /// /// Creates a new instance based on this instance /// /// public ResourceElementSet Clone() => new ResourceElementSet(ResourceReaderTypeName, ResourceSetTypeName, ReaderType) { FormatVersion = FormatVersion }; } }