25using System.Collections.Concurrent;
27using System.Reflection;
36 internal sealed class VfsAssemblyDirectory : VfsDirectory
39 readonly ConcurrentDictionary<Assembly, VfsDirectory> directories =
new ConcurrentDictionary<Assembly, VfsDirectory>();
45 public VfsAssemblyDirectory(VfsContext context) :
61 var sb =
new ValueStringBuilder();
63 for (var i = 0; i <= directoryName.Length; i++)
65 if (i == directoryName.Length || directoryName[i] ==
'_')
67 if (i < directoryName.Length - 1 && directoryName[i + 1] ==
'!')
72 else if (i == directoryName.Length || directoryName[i + 1] ==
'_')
77 assemblyName.Name = sb.ToString();
80 assemblyName.Version = Version.Parse(sb.ToString());
83 assemblyName.SetPublicKeyToken(StringToByteArray(sb.ToString()));
86 assemblyName.CultureName = sb.ToString();
99 while (
'0' <= directoryName[end] && directoryName[end] <=
'9')
103 if (directoryName[end] !=
'_' || !
int.TryParse(directoryName.Substring(start, end - start), out
int repeatCount))
105 if (directoryName[end] !=
'_' || !
int.TryParse(directoryName.AsSpan(start, end - start), out
int repeatCount))
109 sb.Append(
'_', repeatCount);
115 sb.Append(directoryName[i]);
132 public override VfsEntry GetEntry(
string name)
135 if (Guid.TryParse(name, out var guid))
137 foreach (var assemblyName
in Context.GetAssemblyNames())
138 if (Context.GetAssembly(assemblyName) is
Assembly assembly)
139 if (assembly.ManifestModule.ModuleVersionId == guid && assembly.IsDynamic ==
false)
140 return directories.GetOrAdd(assembly, CreateAssemblyDirectory);
147 var assemblyName = ParseDirectoryName(name);
148 if (assemblyName !=
null)
150 var assembly = Context.GetAssembly(assemblyName);
151 if (assembly !=
null && assembly.IsDynamic ==
false && name == VfsTable.GetAssemblyDirectoryName(Context, assembly))
152 return directories.GetOrAdd(assembly, CreateAssemblyDirectory);
164 VfsDirectory CreateAssemblyDirectory(
Assembly assembly)
166 var d =
new VfsEntryDirectory(Context);
167 d.AddEntry(
"resources",
new VfsAssemblyResourceDirectory(Context, assembly));
168 d.AddEntry(
"classes",
new VfsAssemblyClassDirectory(Context, assembly,
""));
176 public override string[] List()
178 return Array.Empty<
string>();
187 byte[] StringToByteArray(
string hex)
189 if (hex.Length % 2 == 1)
190 throw new Exception(
"The binary key cannot have an odd number of digits");
192 var arr =
new byte[hex.Length >> 1];
193 for (
int i = 0; i < hex.Length >> 1; ++i)
194 arr[i] = (
byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
198 static int GetHexVal(
char hex) => (int)hex - ((
int)hex < 58 ? 48 : ((
int)hex < 97 ? 55 : 87));
IKVM.Reflection.Assembly Assembly
IKVM.Reflection.AssemblyName AssemblyName