| | | 1 | | using System; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using System.IO; |
| | | 4 | | using System.Linq; |
| | | 5 | | |
| | | 6 | | namespace DirectSight.Common; |
| | | 7 | | |
| | | 8 | | /// <summary> |
| | | 9 | | /// Searches files based on file pattern with support for wildcards. |
| | | 10 | | /// </summary> |
| | | 11 | | internal static class WildCardFileSearch |
| | | 12 | | { |
| | | 13 | | /// <summary> |
| | | 14 | | /// Gets the files matching the given file pattern.. |
| | | 15 | | /// </summary> |
| | | 16 | | /// <param name="pattern">The file pattern.</param> |
| | | 17 | | /// <returns>The files.</returns> |
| | | 18 | | internal static IEnumerable<string> GetFiles(string pattern) |
| | 11 | 19 | | { |
| | 11 | 20 | | if (string.IsNullOrEmpty(pattern)) |
| | 2 | 21 | | { |
| | 2 | 22 | | throw new ArgumentException("Pattern must not be empty.", nameof(pattern)); |
| | | 23 | | } |
| | | 24 | | |
| | 9 | 25 | | if (pattern.Intersect(Path.GetInvalidPathChars()).Any()) |
| | 0 | 26 | | { |
| | 0 | 27 | | throw new ArgumentException("Pattern contains invalid character.", nameof(pattern)); |
| | | 28 | | } |
| | | 29 | | |
| | 9 | 30 | | pattern = pattern.Replace('/', Path.DirectorySeparatorChar); |
| | | 31 | | |
| | 9 | 32 | | bool pathRooted = Path.IsPathRooted(pattern); |
| | | 33 | | |
| | 9 | 34 | | if (!pathRooted) |
| | 2 | 35 | | { |
| | 2 | 36 | | pattern = Path.Combine(Directory.GetCurrentDirectory(), pattern); |
| | 2 | 37 | | } |
| | | 38 | | |
| | 9 | 39 | | string[] parts = pattern.Split([Path.DirectorySeparatorChar], StringSplitOptions.RemoveEmptyEntries); |
| | | 40 | | |
| | 9 | 41 | | if (pathRooted && parts.Length < 2) |
| | 3 | 42 | | { |
| | 3 | 43 | | throw new ArgumentException("Pattern in no valid file pattern.", nameof(pattern)); |
| | | 44 | | } |
| | | 45 | | |
| | 6 | 46 | | bool directoryIsUNCPath = pattern.StartsWith(@"\\", StringComparison.Ordinal); |
| | | 47 | | |
| | 6 | 48 | | if (directoryIsUNCPath) |
| | 0 | 49 | | { |
| | 0 | 50 | | parts[0] = @"\\" + parts[0]; |
| | 0 | 51 | | } |
| | 6 | 52 | | else if (pattern.StartsWith(@"\", StringComparison.Ordinal)) |
| | 0 | 53 | | { |
| | 0 | 54 | | parts[0] = @"\" + parts[0]; |
| | 0 | 55 | | } |
| | | 56 | | |
| | 6 | 57 | | if (pattern.StartsWith("/", StringComparison.Ordinal)) |
| | 6 | 58 | | { |
| | 6 | 59 | | parts[0] = "/" + parts[0]; |
| | 6 | 60 | | } |
| | | 61 | | |
| | 6 | 62 | | if (parts[0].EndsWith(":")) |
| | 0 | 63 | | { |
| | 0 | 64 | | parts[0] = parts[0] + Path.DirectorySeparatorChar; |
| | 0 | 65 | | } |
| | | 66 | | |
| | 6 | 67 | | string[] directoryParts = parts.Take(parts.Length - 1).ToArray(); |
| | | 68 | | |
| | 6 | 69 | | string filePattern = parts.Last(); |
| | | 70 | | |
| | 36 | 71 | | foreach (string directory in GetDirectories(directoryParts[0], directoryParts, 1, directoryIsUNCPath)) |
| | 9 | 72 | | { |
| | 9 | 73 | | if (Directory.Exists(directory)) |
| | 9 | 74 | | { |
| | 261 | 75 | | foreach (string file in Directory.EnumerateFiles(directory, filePattern)) |
| | 117 | 76 | | { |
| | 117 | 77 | | yield return file; |
| | 117 | 78 | | } |
| | 9 | 79 | | } |
| | 9 | 80 | | } |
| | 6 | 81 | | } |
| | | 82 | | |
| | | 83 | | /// <summary> |
| | | 84 | | /// Gets the directories matching the given directory parts. |
| | | 85 | | /// </summary> |
| | | 86 | | /// <param name="directory">The directory.</param> |
| | | 87 | | /// <param name="directoryParts">The directory parts.</param> |
| | | 88 | | /// <param name="currentIndex">Index of the current part.</param> |
| | | 89 | | /// <param name="directoryIsUNCPath">if set to <c>true</c> directory is UNC path.</param> |
| | | 90 | | /// <returns>The directories.</returns> |
| | | 91 | | private static IEnumerable<string> GetDirectories(string directory, string[] directoryParts, int currentIndex, bool |
| | 49 | 92 | | { |
| | | 93 | | // UNC paths need special treatment Directory.Exists("\\SomeUNCPath") returns false if no subdirectory is specif |
| | 49 | 94 | | if (!Directory.Exists(directory) && !(currentIndex == 1 && directoryIsUNCPath)) |
| | 1 | 95 | | { |
| | 1 | 96 | | yield break; |
| | | 97 | | } |
| | | 98 | | |
| | 48 | 99 | | if (currentIndex >= directoryParts.Length) |
| | 9 | 100 | | { |
| | 9 | 101 | | yield return directory; |
| | 9 | 102 | | } |
| | 39 | 103 | | else if (directoryParts[currentIndex].Contains("*")) |
| | 7 | 104 | | { |
| | 7 | 105 | | var subDirectories = Directory.EnumerateDirectories(directory, directoryParts[currentIndex]); |
| | | 106 | | |
| | 43 | 107 | | foreach (var subDirectory in subDirectories) |
| | 11 | 108 | | { |
| | 11 | 109 | | var subsubDirectories = GetDirectories(subDirectory, directoryParts, currentIndex + 1, directoryIsUNCPat |
| | | 110 | | |
| | 53 | 111 | | foreach (var subsubDirectory in subsubDirectories) |
| | 10 | 112 | | { |
| | 10 | 113 | | yield return subsubDirectory; |
| | 10 | 114 | | } |
| | 11 | 115 | | } |
| | 7 | 116 | | } |
| | | 117 | | else |
| | 32 | 118 | | { |
| | 32 | 119 | | directory = Path.Combine(directory, directoryParts[currentIndex]); |
| | | 120 | | |
| | 32 | 121 | | var subsubDirectories = GetDirectories(directory, directoryParts, currentIndex + 1, directoryIsUNCPath); |
| | | 122 | | |
| | 206 | 123 | | foreach (var subsubDirectory in subsubDirectories) |
| | 55 | 124 | | { |
| | 55 | 125 | | yield return subsubDirectory; |
| | 55 | 126 | | } |
| | 32 | 127 | | } |
| | 48 | 128 | | } |
| | | 129 | | } |