public NamePart(string path, int index, int length, NamePartKind kind) { Path = path ?? throw new ArgumentNullException(nameof(path)); Index = index; Length = length; Kind = kind; }
internal static FileSystemFinderResult?MatchFile( string path, Filter nameFilter, Filter extensionFilter, FileSystemFinderOptions options, IProgress <FileSystemFinderProgress> progress, NamePartKind namePartKind) { if (options.Attributes != 0 && (File.GetAttributes(path) & options.Attributes) != options.Attributes) { return(null); } progress?.Report(new FileSystemFinderProgress(path, ProgressKind.File)); if (extensionFilter?.IsMatch(NamePart.FromFile(path, extensionFilter.NamePart)) == false) { return(null); } NamePart namePart = NamePart.FromFile(path, namePartKind); Match match = null; if (nameFilter != null) { match = (options.PartOnly) ? nameFilter.Regex.Match(namePart.ToString()) : nameFilter.Regex.Match(path, namePart.Index, namePart.Length); if (!nameFilter.IsMatch(match)) { return(null); } } if (options.Empty != null) { try { if ((options.Empty.Value) ? !FileSystemHelpers.IsEmptyFile(path) : FileSystemHelpers.IsEmptyFile(path)) { return(null); } } catch (Exception ex) when(ex is IOException || ex is UnauthorizedAccessException) { progress?.Report(new FileSystemFinderProgress(path, ProgressKind.File, ex)); return(null); } } return(new FileSystemFinderResult(namePart, match)); }
internal static FileSystemFinderResult MatchDirectory( string path, Filter nameFilter, FileSystemFinderOptions options, IProgress <FileSystemFinderProgress> progress, NamePartKind namePartKind) { if (options.Attributes != 0 && (File.GetAttributes(path) & options.Attributes) != options.Attributes) { return(null); } progress?.Report(new FileSystemFinderProgress(path, ProgressKind.Directory)); NamePart namePart = NamePart.FromDirectory(path, namePartKind); Match match = null; if (nameFilter != null) { match = (options.PartOnly) ? nameFilter.Regex.Match(namePart.ToString()) : nameFilter.Regex.Match(path, namePart.Index, namePart.Length); if (!nameFilter.IsMatch(match)) { return(null); } } if (options.Empty != null) { try { if ((options.Empty.Value) ? !IsEmptyDirectory(path) : IsEmptyDirectory(path)) { return(null); } } catch (Exception ex) when(ex is IOException || ex is UnauthorizedAccessException) { progress?.Report(new FileSystemFinderProgress(path, ProgressKind.Directory, ex)); return(null); } } return(new FileSystemFinderResult(namePart, match, isDirectory: true)); }
public Filter( Regex regex, NamePartKind namePart = NamePartKind.Name, int groupNumber = -1, bool isNegative = false, Func <Capture, bool> predicate = null) { Regex = regex ?? throw new ArgumentNullException(nameof(regex)); Debug.Assert(groupNumber < 0 || regex.GetGroupNumbers().Contains(groupNumber), groupNumber.ToString()); GroupNumber = groupNumber; IsNegative = isNegative; NamePart = namePart; Predicate = predicate; }
public static NamePart FromFile(string path, NamePartKind kind) { switch (kind) { case NamePartKind.Name: { int index = FileSystemHelpers.GetFileNameIndex(path); return(new NamePart(path, index, path.Length - index, kind)); } case NamePartKind.FullName: { return(new NamePart(path, 0, path.Length, kind)); } case NamePartKind.NameWithoutExtension: { int index = FileSystemHelpers.GetFileNameIndex(path); int dotIndex = GetExtensionIndex(path); return(new NamePart(path, index, dotIndex - index, kind)); } case NamePartKind.Extension: { int dotIndex = GetExtensionIndex(path); if (dotIndex >= path.Length - 1) { return(new NamePart(path, path.Length, 0, kind)); } return(new NamePart(path, dotIndex + 1, path.Length - dotIndex - 1, kind)); } default: { throw new ArgumentException("", nameof(kind)); } } }
public static NamePart FromDirectory(string path, NamePartKind kind) { switch (kind) { case NamePartKind.Name: case NamePartKind.NameWithoutExtension: { int index = FileSystemHelpers.GetFileNameIndex(path); return(new NamePart(path, index, path.Length - index, kind)); } case NamePartKind.FullName: { return(new NamePart(path, 0, path.Length, kind)); } case NamePartKind.Extension: { return(default); }
public static bool TryParse( IEnumerable <string> values, string optionName, OptionValueProvider provider, out Filter filter, bool allowNull = false, NamePartKind defaultNamePart = NamePartKind.Name, PatternOptions includedPatternOptions = PatternOptions.None) { filter = null; string pattern = values.FirstOrDefault(); if (pattern == null) { if (allowNull) { return(true); } else { throw new InvalidOperationException($"Option '{OptionNames.GetHelpText(optionName)}' is required."); } } TimeSpan matchTimeout = Regex.InfiniteMatchTimeout; string groupName = null; NamePartKind namePart = defaultNamePart; string separator = null; Func <Capture, bool> predicate = null; List <string> options = null; foreach (string option in values.Skip(1)) { int index = option.IndexOf("="); if (index != -1) { string key = option.Substring(0, index); string value = option.Substring(index + 1); if (OptionValues.Group.IsKeyOrShortKey(key)) { groupName = value; continue; } else if (OptionValues.ListSeparator.IsKeyOrShortKey(key)) { separator = value; continue; } else if (OptionValues.Part.IsKeyOrShortKey(key)) { if (!TryParseAsEnum(value, out namePart, provider: OptionValueProviders.NamePartKindProvider)) { string helpText = OptionValueProviders.NamePartKindProvider.GetHelpText(); WriteError($"Option '{OptionValues.Part.HelpValue}' has invalid value '{value}'. Allowed values: {helpText}."); return(false); } continue; } else if (OptionValues.Timeout.IsKeyOrShortKey(key)) { if (!TryParseMatchTimeout(value, out matchTimeout)) { WriteError($"Option '{OptionValues.Timeout.HelpValue}' has invalid value '{value}'."); return(false); } continue; } } if (Expression.TryParse(option, out Expression expression)) { if (OptionValues.Length.IsKeyOrShortKey(expression.Identifier)) { try { predicate = PredicateHelpers.GetLengthPredicate(expression); continue; } catch (ArgumentException) { WriteError($"Option '{OptionNames.GetHelpText(optionName)}' has invalid value '{option}'."); return(false); } } else { WriteError($"Option '{OptionNames.GetHelpText(optionName)}' has invalid value '{option}'. Allowed values: {provider.GetHelpText()}."); return(false); } } (options ?? (options = new List <string>())).Add(option); } if (!TryParseRegexOptions(options, optionName, out RegexOptions regexOptions, out PatternOptions patternOptions, includedPatternOptions, provider)) { return(false); } switch (patternOptions & (PatternOptions.WholeWord | PatternOptions.WholeLine)) { case PatternOptions.None: case PatternOptions.WholeWord: case PatternOptions.WholeLine: { break; } default: { WriteError($"Values '{OptionValueProviders.PatternOptionsProvider.GetValue(nameof(PatternOptions.WholeWord)).HelpValue}' and '{OptionValueProviders.PatternOptionsProvider.GetValue(nameof(PatternOptions.WholeLine)).HelpValue}' cannot be combined."); return(false); } } if ((patternOptions & PatternOptions.FromFile) != 0 && !FileSystemHelpers.TryReadAllText(pattern, out pattern)) { return(false); } pattern = BuildPattern(pattern, patternOptions, separator); Regex regex = null; try { regex = new Regex(pattern, regexOptions, matchTimeout); } catch (ArgumentException ex) { WriteError(ex, $"Could not parse regular expression: {ex.Message}"); return(false); } int groupIndex = -1; if (groupName != null) { groupIndex = regex.GroupNumberFromName(groupName); if (groupIndex == -1) { string message = $"Group '{groupName}' does not exist."; string[] groupNames = regex.GetGroupNames(); if (groupNames.Length > 1) { message += $" Existing group names: {TextHelpers.Join(", ", " and ", groupNames.Where(f => f != "0"))}."; } WriteError(message); return(false); } } filter = new Filter( regex, namePart: namePart, groupNumber: groupIndex, isNegative: (patternOptions & PatternOptions.Negative) != 0, predicate); return(true); }
public static IEnumerable <FileSystemFinderResult> Find( string directoryPath, Filter nameFilter = null, Filter extensionFilter = null, Filter directoryFilter = null, FileSystemFinderOptions options = null, IProgress <FileSystemFinderProgress> progress = null, INotifyDirectoryChanged notifyDirectoryChanged = null, CancellationToken cancellationToken = default) { if (options == null) { options = FileSystemFinderOptions.Default; } var enumerationOptions = new EnumerationOptions() { AttributesToSkip = options.AttributesToSkip, IgnoreInaccessible = options.IgnoreInaccessible, MatchCasing = options.MatchCasing, MatchType = options.MatchType, RecurseSubdirectories = false, ReturnSpecialDirectories = options.ReturnSpecialDirectories }; NamePartKind namePart = nameFilter?.NamePart ?? NamePartKind.Name; NamePartKind directoryNamePart = directoryFilter?.NamePart ?? NamePartKind.Name; var directories = new Queue <string>(); Queue <string> subDirectories = (options.RecurseSubdirectories) ? new Queue <string>() : null; string currentDirectory = null; if (notifyDirectoryChanged != null) { notifyDirectoryChanged.DirectoryChanged += (object sender, DirectoryChangedEventArgs e) => currentDirectory = e.NewName; } string dirPath = directoryPath; while (true) { progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory)); if (options.SearchTarget != SearchTarget.Directories) { IEnumerator <string> fi = null; try { fi = (options.CanEnumerate) ? Directory.EnumerateFiles(dirPath, "*", enumerationOptions).GetEnumerator() : ((IEnumerable <string>)Directory.GetFiles(dirPath, "*", enumerationOptions)).GetEnumerator(); } catch (Exception ex) when(IsWellKnownException(ex)) { progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory, ex)); } if (fi != null) { using (fi) { while (fi.MoveNext()) { FileSystemFinderResult?result = MatchFile(fi.Current, nameFilter, extensionFilter, options, progress, namePart); if (result != null) { yield return(result.Value); } cancellationToken.ThrowIfCancellationRequested(); } } } } IEnumerator <string> di = null; try { di = (options.CanEnumerate) ? Directory.EnumerateDirectories(dirPath, "*", enumerationOptions).GetEnumerator() : ((IEnumerable <string>)Directory.GetDirectories(dirPath, "*", enumerationOptions)).GetEnumerator(); } catch (Exception ex) when(IsWellKnownException(ex)) { progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory, ex)); } if (di != null) { using (di) { while (di.MoveNext()) { currentDirectory = di.Current; if (directoryFilter?.IsMatch(NamePart.FromDirectory(currentDirectory, directoryNamePart)) != false) { if (options.SearchTarget != SearchTarget.Files && namePart != NamePartKind.Extension) { FileSystemFinderResult?result = MatchDirectory(currentDirectory, nameFilter, options, progress); if (result != null) { yield return(result.Value); } } if (currentDirectory != null && options.RecurseSubdirectories) { subDirectories !.Enqueue(currentDirectory); } } cancellationToken.ThrowIfCancellationRequested(); } } if (options.RecurseSubdirectories) { while (subDirectories !.Count > 0) { directories.Enqueue(subDirectories.Dequeue()); } } } if (directories.Count > 0) { dirPath = directories.Dequeue(); } else { break; } } }