208 lines
9.3 KiB
C#
208 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
|
|
namespace Costura;
|
|
|
|
[CompilerGenerated]
|
|
internal static class AssemblyLoader
|
|
{
|
|
private static object nullCacheLock = new object();
|
|
|
|
private static Dictionary<string, bool> nullCache = new Dictionary<string, bool>();
|
|
|
|
private static Dictionary<string, string> assemblyNames = new Dictionary<string, string>();
|
|
|
|
private static Dictionary<string, string> symbolNames = new Dictionary<string, string>();
|
|
|
|
private static int isAttached;
|
|
|
|
private static string CultureToString(CultureInfo culture)
|
|
{
|
|
if (culture == null)
|
|
{
|
|
return "";
|
|
}
|
|
return culture.Name;
|
|
}
|
|
|
|
private static Assembly ReadExistingAssembly(AssemblyName name)
|
|
{
|
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
|
Assembly[] assemblies = currentDomain.GetAssemblies();
|
|
Assembly[] array = assemblies;
|
|
foreach (Assembly assembly in array)
|
|
{
|
|
AssemblyName name2 = assembly.GetName();
|
|
if (string.Equals(name2.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) && string.Equals(CultureToString(name2.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return assembly;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static void CopyTo(Stream source, Stream destination)
|
|
{
|
|
byte[] array = new byte[81920];
|
|
int count;
|
|
while ((count = source.Read(array, 0, array.Length)) != 0)
|
|
{
|
|
destination.Write(array, 0, count);
|
|
}
|
|
}
|
|
|
|
private static Stream LoadStream(string fullName)
|
|
{
|
|
Assembly executingAssembly = Assembly.GetExecutingAssembly();
|
|
if (fullName.EndsWith(".compressed"))
|
|
{
|
|
using (Stream stream = executingAssembly.GetManifestResourceStream(fullName))
|
|
{
|
|
using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress);
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
CopyTo(source, memoryStream);
|
|
memoryStream.Position = 0L;
|
|
return memoryStream;
|
|
}
|
|
}
|
|
return executingAssembly.GetManifestResourceStream(fullName);
|
|
}
|
|
|
|
private static Stream LoadStream(Dictionary<string, string> resourceNames, string name)
|
|
{
|
|
if (resourceNames.TryGetValue(name, out var value))
|
|
{
|
|
return LoadStream(value);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static byte[] ReadStream(Stream stream)
|
|
{
|
|
byte[] array = new byte[stream.Length];
|
|
stream.Read(array, 0, array.Length);
|
|
return array;
|
|
}
|
|
|
|
private static Assembly ReadFromEmbeddedResources(Dictionary<string, string> assemblyNames, Dictionary<string, string> symbolNames, AssemblyName requestedAssemblyName)
|
|
{
|
|
string text = requestedAssemblyName.Name.ToLowerInvariant();
|
|
if (requestedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name))
|
|
{
|
|
text = requestedAssemblyName.CultureInfo.Name + "." + text;
|
|
}
|
|
byte[] rawAssembly;
|
|
using (Stream stream = LoadStream(assemblyNames, text))
|
|
{
|
|
if (stream == null)
|
|
{
|
|
return null;
|
|
}
|
|
rawAssembly = ReadStream(stream);
|
|
}
|
|
using (Stream stream2 = LoadStream(symbolNames, text))
|
|
{
|
|
if (stream2 != null)
|
|
{
|
|
byte[] rawSymbolStore = ReadStream(stream2);
|
|
return Assembly.Load(rawAssembly, rawSymbolStore);
|
|
}
|
|
}
|
|
return Assembly.Load(rawAssembly);
|
|
}
|
|
|
|
public static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
|
|
{
|
|
lock (nullCacheLock)
|
|
{
|
|
if (nullCache.ContainsKey(e.Name))
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
AssemblyName assemblyName = new AssemblyName(e.Name);
|
|
Assembly assembly = ReadExistingAssembly(assemblyName);
|
|
if ((object)assembly != null)
|
|
{
|
|
return assembly;
|
|
}
|
|
assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName);
|
|
if ((object)assembly == null)
|
|
{
|
|
lock (nullCacheLock)
|
|
{
|
|
nullCache[e.Name] = true;
|
|
}
|
|
if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != AssemblyNameFlags.None)
|
|
{
|
|
assembly = Assembly.Load(assemblyName);
|
|
}
|
|
}
|
|
return assembly;
|
|
}
|
|
|
|
static AssemblyLoader()
|
|
{
|
|
assemblyNames.Add("costura", "costura.costura.dll.compressed");
|
|
symbolNames.Add("costura", "costura.costura.pdb.compressed");
|
|
assemblyNames.Add("cs.microsoft.codeanalysis.csharp.resources", "costura.cs.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("cs.microsoft.codeanalysis.resources", "costura.cs.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("de.microsoft.codeanalysis.csharp.resources", "costura.de.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("de.microsoft.codeanalysis.resources", "costura.de.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("es.microsoft.codeanalysis.csharp.resources", "costura.es.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("es.microsoft.codeanalysis.resources", "costura.es.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("fr.microsoft.codeanalysis.csharp.resources", "costura.fr.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("fr.microsoft.codeanalysis.resources", "costura.fr.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("it.microsoft.codeanalysis.csharp.resources", "costura.it.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("it.microsoft.codeanalysis.resources", "costura.it.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("ja.microsoft.codeanalysis.csharp.resources", "costura.ja.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("ja.microsoft.codeanalysis.resources", "costura.ja.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("ko.microsoft.codeanalysis.csharp.resources", "costura.ko.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("ko.microsoft.codeanalysis.resources", "costura.ko.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("microsoft.bcl.asyncinterfaces", "costura.microsoft.bcl.asyncinterfaces.dll.compressed");
|
|
assemblyNames.Add("microsoft.codeanalysis.csharp", "costura.microsoft.codeanalysis.csharp.dll.compressed");
|
|
symbolNames.Add("microsoft.codeanalysis.csharp", "costura.microsoft.codeanalysis.csharp.pdb.compressed");
|
|
assemblyNames.Add("microsoft.codeanalysis", "costura.microsoft.codeanalysis.dll.compressed");
|
|
symbolNames.Add("microsoft.codeanalysis", "costura.microsoft.codeanalysis.pdb.compressed");
|
|
assemblyNames.Add("pl.microsoft.codeanalysis.csharp.resources", "costura.pl.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("pl.microsoft.codeanalysis.resources", "costura.pl.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("pt-br.microsoft.codeanalysis.csharp.resources", "costura.pt-br.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("pt-br.microsoft.codeanalysis.resources", "costura.pt-br.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("ru.microsoft.codeanalysis.csharp.resources", "costura.ru.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("ru.microsoft.codeanalysis.resources", "costura.ru.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("system.buffers", "costura.system.buffers.dll.compressed");
|
|
assemblyNames.Add("system.collections.immutable", "costura.system.collections.immutable.dll.compressed");
|
|
assemblyNames.Add("system.diagnostics.diagnosticsource", "costura.system.diagnostics.diagnosticsource.dll.compressed");
|
|
assemblyNames.Add("system.memory", "costura.system.memory.dll.compressed");
|
|
assemblyNames.Add("system.numerics.vectors", "costura.system.numerics.vectors.dll.compressed");
|
|
assemblyNames.Add("system.reflection.metadata", "costura.system.reflection.metadata.dll.compressed");
|
|
assemblyNames.Add("system.runtime.compilerservices.unsafe", "costura.system.runtime.compilerservices.unsafe.dll.compressed");
|
|
assemblyNames.Add("system.text.encoding.codepages", "costura.system.text.encoding.codepages.dll.compressed");
|
|
assemblyNames.Add("system.text.encodings.web", "costura.system.text.encodings.web.dll.compressed");
|
|
assemblyNames.Add("system.text.json", "costura.system.text.json.dll.compressed");
|
|
assemblyNames.Add("system.threading.tasks.extensions", "costura.system.threading.tasks.extensions.dll.compressed");
|
|
assemblyNames.Add("system.valuetuple", "costura.system.valuetuple.dll.compressed");
|
|
assemblyNames.Add("tr.microsoft.codeanalysis.csharp.resources", "costura.tr.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("tr.microsoft.codeanalysis.resources", "costura.tr.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("zh-hans.microsoft.codeanalysis.csharp.resources", "costura.zh-hans.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("zh-hans.microsoft.codeanalysis.resources", "costura.zh-hans.microsoft.codeanalysis.resources.dll.compressed");
|
|
assemblyNames.Add("zh-hant.microsoft.codeanalysis.csharp.resources", "costura.zh-hant.microsoft.codeanalysis.csharp.resources.dll.compressed");
|
|
assemblyNames.Add("zh-hant.microsoft.codeanalysis.resources", "costura.zh-hant.microsoft.codeanalysis.resources.dll.compressed");
|
|
}
|
|
|
|
public static void Attach()
|
|
{
|
|
if (Interlocked.Exchange(ref isAttached, 1) != 1)
|
|
{
|
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
|
currentDomain.AssemblyResolve += ResolveAssembly;
|
|
}
|
|
}
|
|
}
|