Example #1
0
        public IEnumerable <string> EnumerateDirectories(string path, string pattern, SearchOption searchOption)
        {
            if (!IsPathInCone(path, out string processedPath))
            {
                //TODO: Handle cases where part of the directory set is inside our cone and part is not
                foreach (string s in _basis.EnumerateDirectories(path, pattern, searchOption))
                {
                    yield return(s);
                }

                yield break;
            }

            path = processedPath;
            string rel = path.Substring(_root.FullPath.Length).Trim('/', '\\');
            FileSystemDirectory currentDir = _root;

            if (!string.IsNullOrEmpty(rel))
            {
                string[] parts = rel.Split('/', '\\');
                for (int i = 0; i < parts.Length; ++i)
                {
                    FileSystemDirectory dir;
                    if (!currentDir.Directories.TryGetValue(parts[i], out dir))
                    {
                        yield break;
                    }

                    currentDir = dir;
                }
            }

            Regex rx = new Regex(Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", "."));

            if (searchOption == SearchOption.TopDirectoryOnly)
            {
                foreach (KeyValuePair <string, FileSystemDirectory> entry in currentDir.Directories)
                {
                    if (rx.IsMatch(entry.Key))
                    {
                        yield return(entry.Value.FullPath);
                    }
                }

                yield break;
            }

            Stack <IEnumerator <KeyValuePair <string, FileSystemDirectory> > > directories = new Stack <IEnumerator <KeyValuePair <string, FileSystemDirectory> > >();
            IEnumerator <KeyValuePair <string, FileSystemDirectory> >          current     = currentDir.Directories.GetEnumerator();
            bool moveNext;

            while ((moveNext = current.MoveNext()) || directories.Count > 0)
            {
                while (!moveNext)
                {
                    current.Dispose();

                    if (directories.Count == 0)
                    {
                        break;
                    }

                    current  = directories.Pop();
                    moveNext = current.MoveNext();
                }

                if (!moveNext)
                {
                    break;
                }

                if (rx.IsMatch(current.Current.Key))
                {
                    yield return(current.Current.Value.FullPath);
                }

                directories.Push(current);
                current = current.Current.Value.Directories.GetEnumerator();
            }
        }