private IVirtualDirectory GetVirtualDirectoryForPath(string path)
{
//Yes, this is a lot of work to do in a lock. However my belief is that, in practice,
// it will be pretty unlikely that multiple threads will contend for this lock, especially
//as it will only be held for any substantial period of time while constructing a previously
//unseen archive
lock (_directoryLock)
{
//After profiling, it turns out ZipFileAtRoot is very expensive, so
//I'm going to some trouble to avoid it.
foreach (string key in _directories.Keys)
{
if (path.StartsWith(key, StringComparison.CurrentCultureIgnoreCase))
return _directories[key];
}
if (path.IndexOf(".zip", StringComparison.CurrentCultureIgnoreCase) <= 0 &&
path.IndexOf(VirtualFileUtils.OBSCURED_ARCHIVE_EXTENSION, StringComparison.CurrentCultureIgnoreCase) <= 0)
return null;
string zipRoot = VirtualFileUtils.ZipFileAtRoot(path);
if (zipRoot == null)
return null;
if (File.Exists(zipRoot))
{
_directories.Add(zipRoot, new ZipArchiveDirectory(zipRoot));
return _directories[zipRoot];
}
return null;
}
}