/// <summary> /// Tries to get the path to a directory, recursively adding all the directories above it if necessary /// </summary> /// <param name="Info">Info for the directory to find</param> /// <param name="Result">On success, receives the directory</param> /// <returns>True if the directory exists</returns> static bool TryGetDirectoryInternal(DirectoryInfo Info, out WorkspaceDirectory Result) { DirectoryInfo ParentInfo = Info.Parent; if (ParentInfo == null) { // Try to find an existing root directory that matches this directory, or add a new one DirectoryReference Location = new DirectoryReference(Info); if (!RootDirectories.TryGetValue(Location, out Result)) { Result = RootDirectories.GetOrAdd(Location, new WorkspaceDirectory(Info)); } return(true); } else { // Get the parent directory WorkspaceDirectory ParentDirectory; if (!TryGetDirectoryInternal(ParentInfo, out ParentDirectory)) { Result = null; return(false); } // Look for a directory within this directory return(ParentDirectory.TryGetDirectory(Info.Name, out Result)); } }
/// <summary> /// Caches all the files under the given directory /// </summary> /// <param name="Directory">The directory to cache</param> public static void CacheFiles(WorkspaceDirectory Directory) { using (ThreadPoolWorkQueue WorkQueue = new ThreadPoolWorkQueue()) { WorkQueue.Enqueue(new WorkspaceScanner(Directory)); } }
/// <summary> /// Callback from the thread pool worker /// </summary> /// <param name="Queue">The queue calling this method</param> public void Run(ThreadPoolWorkQueue Queue) { WorkspaceDirectory CurrentDirectory = Directory; while (CurrentDirectory != null) { CurrentDirectory.CacheFiles(); CurrentDirectory.CacheDirectories(); if (CurrentDirectory.NormalizedPathFromBranchRoot != null && !Rules.SearchDirectoryForSource(Directory.NormalizedPathFromBranchRoot)) { break; } WorkspaceDirectory NextDirectory = null; foreach (WorkspaceDirectory ChildDirectory in CurrentDirectory.Directories) { if (NextDirectory == null) { NextDirectory = ChildDirectory; } else { Queue.Enqueue(new WorkspaceScanner(ChildDirectory)); } } CurrentDirectory = NextDirectory; } }
/// <summary> /// Constructor /// </summary> /// <param name="Name">Name of the file</param> /// <param name="Directory">The directory containing the file</param> public WorkspaceFile(string Name, WorkspaceDirectory Directory) { this.Location = FileReference.Combine(Directory.Location, Name); this.Directory = Directory; if (Directory.NormalizedPathFromBranchRoot != null) { this.NormalizedPathFromBranchRoot = Directory.NormalizedPathFromBranchRoot + Name.ToLowerInvariant(); } }
/// <summary> /// Construct a directory object, as a child of the given parent directory /// </summary> /// <param name="Info">Info for the directory to represent</param> /// <param name="ParentDirectory">The </param> WorkspaceDirectory(DirectoryInfo Info, WorkspaceDirectory ParentDirectory) { this.Location = DirectoryReference.Combine(ParentDirectory.Location, Info.Name); this.ParentDirectory = ParentDirectory; this.Info = Info; if (ParentDirectory.NormalizedPathFromBranchRoot != null) { NormalizedPathFromBranchRoot = ParentDirectory.NormalizedPathFromBranchRoot + Info.Name.ToLowerInvariant() + "/"; } }
/// <summary> /// Construct a directory object with the given DirectoryInfo as the root /// </summary> /// <param name="Info">Info for the directory to represent</param> /// <param name="bIsBranchRoot">Whether this directory is the root of the branch</param> public WorkspaceDirectory(DirectoryInfo Info) { if (Info.Parent != null) { throw new Exception("WorkspaceDirectory may only be constructed directly for a root directory"); } this.Location = new DirectoryReference(Info.FullName); this.ParentDirectory = null; this.Info = Info; }
/// <summary> /// Caches the directories in this directory /// </summary> public void CacheDirectories() { if (NameToDirectory == null) { Dictionary <string, WorkspaceDirectory> NewNameToDirectory = new Dictionary <string, WorkspaceDirectory>(StringComparer.InvariantCultureIgnoreCase); foreach (DirectoryInfo DirectoryInfo in Info.EnumerateDirectories()) { WorkspaceDirectory Directory = new WorkspaceDirectory(DirectoryInfo, this); NewNameToDirectory.Add(DirectoryInfo.Name, Directory); } Interlocked.CompareExchange(ref NameToDirectory, NewNameToDirectory, null); } }
/// <summary> /// Gets a WorkspaceFile object for the file at the given location. Throws an exception if the file does not exist. /// </summary> /// <param name="Location">Location of the file</param> /// <returns>The unique WorkspaceFile object for the given file</returns> public static WorkspaceFile GetFile(FileReference Location) { // Find the parent directory WorkspaceDirectory Directory = GetDirectory(Location.Directory); // Find the file within it WorkspaceFile Result; if (!Directory.TryGetFile(Location.GetFileName(), out Result)) { throw new DirectoryNotFoundException(String.Format("Couldn't find file {0}", Location.FullName)); } return(Result); }
/// <summary> /// Sets the location of the branch root directory /// </summary> /// <param name="Location"></param> /// <returns></returns> public static void SetBranchRoot(DirectoryReference Location) { if (RootDirectories.Count > 0) { throw new Exception("Branch root must be set before any other directory queries"); } WorkspaceDirectory NewBranchRoot; if (!TryGetDirectoryInternal(new DirectoryInfo(Location.FullName), out NewBranchRoot)) { throw new DirectoryNotFoundException(String.Format("Couldn't find directory {0}", Location.FullName)); } NewBranchRoot.SetAsBranchRoot(); BranchRoot = NewBranchRoot; }
/// <summary> /// Tries to get a directory of the given name from this directory /// </summary> /// <param name="Name">The name of the directory to look for</param> /// <param name="Result">If successful, receives the directory object</param> /// <returns>True if the directory was found</returns> public bool TryGetDirectory(string Name, out WorkspaceDirectory Result) { if (Name.Length == 1 && Name[0] == '.') { Result = this; return(true); } else if (Name.Length == 2 && Name == ".." && ParentDirectory != null) { Result = ParentDirectory; return(true); } else { CacheDirectories(); return(NameToDirectory.TryGetValue(Name, out Result)); } }
/// <summary> /// Constructor /// </summary> /// <param name="ParentDirectory">The directory to scan</param> /// <param name="FoundFiles">The set of files that have been found</param> public WorkspaceReferenceScanner(WorkspaceDirectory ParentDirectory, ConcurrentBag <WorkspaceFile> FoundFiles) { this.ParentDirectory = ParentDirectory; this.FoundFiles = FoundFiles; }
/// <summary> /// Constructor /// </summary> /// <param name="CurrentDirectory">The directory to scan</param> public WorkspaceScanner(WorkspaceDirectory Directory) { this.Directory = Directory; }