예제 #1
0
        /// <summary>
        /// This is the function that actually does the searching.  It creates threads and searches and then
        /// waits for all the results to be sent.
        /// </summary>
        public void internalSearch()
        {
            String searchDirectory = mSearchParams.SearchDirectory;

            if (mRegex != null)
            {
                List <String> fileList = DirectoryCache.get().getFileList();

                if (fileList != null)
                {
                    Stats.TotalFilesToSearch = fileList.Count;
                    Logger.get().AddInfoFormat("{0} files to search", Stats.TotalFilesToSearch);
                    try
                    {
                        // Set up the parallel lambda expression.  The parameters were trial and error trying to get the fastest execution
                        fileList.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(63)
                        .WithCancellation(Stats.CancellationTokenSource.Token)
                        .WithMergeOptions(ParallelMergeOptions.FullyBuffered).ForAll(file =>
                        {
                            // Check for cancellation, this speeds up the cancel after the button is clicked.
                            if (!Stats.CancellationTokenSource.IsCancellationRequested)
                            {
                                if (mSearchParams.FileNameSearch)
                                {
                                    if (mRegex.IsMatch(file))
                                    {
                                        SearchResultList list = new SearchResultList(PathExt.GetRelativePath(searchDirectory, file));
                                        saveResults(list);
                                    }
                                }
                                else
                                {
                                    searchFile(file);
                                }
                            }
                        });
                    }
                    catch (OperationCanceledException)
                    {
                        // Cancelling is not an error, why do they throw an exception?
                    }
                    catch (Exception ex)
                    {
                        Logger.get().AddError(ex.Message);
                    }
                }
                else
                {
                    SearchResultList results = new SearchResultList(DirectoryCache.get().ErrorMessage);
                    mPendingResults.Add(results);
                }
            }
            waitForResultsToBeSent();
        }
        public override void Execute(params string[] args)
        {
            if (CheckHelpAndVersion(args))
            {
                return;
            }
            DemoParsingSetupInfo setupInfo = new DemoParsingSetupInfo();

            ParseArgs(args, setupInfo);

            // check the values in setupInfo

            // enable --time implicitly if there are no other options
            if (setupInfo.ExecutableOptions == 0)
            {
                if (TryGetOption(OptTime.DefaultAliases[0], out var option))
                {
                    option.Enable(null);
                    option.AfterParse(setupInfo);
                }
                else
                {
                    throw new ArgProcessProgrammerException("listdemo option not passed to demo sub-command.");
                }
            }
            // if (setupInfo.OverWriteDemos && !setupInfo.WritesNewDemos) <- I could add a check for this, is it necessary?
            if (setupInfo.OverWriteDemos && setupInfo.EditsDemos && setupInfo.OverwritePrompt)
            {
                Utils.Warning("Warning:");
                Console.WriteLine($" '{OptOverwrite.DefaultAliases[0]}' enabled, this will edit demos and may cause corruption!");
                Console.Write("Are you sure you want to continue? ");
                string?inp = null;
                while (inp != "y")
                {
                    Console.Write("[y/n]");
                    inp = Console.ReadLine()?.Trim().ToLower();
                    if (inp == "n")
                    {
                        return;
                    }
                }
            }

            // flatten directories/files into just files
            foreach (FileSystemInfo fileSystemInfo in _argPaths)
            {
                switch (fileSystemInfo)
                {
                case FileInfo fi:
                    _demoPaths.Add(fi);
                    break;

                case DirectoryInfo di:
                    _demoPaths.UnionWith(Directory.GetFiles(di.FullName, "*.dem",
                                                            setupInfo.ShouldSearchForDemosRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
                                         .Select(s => new FileInfo(s)));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            if (_demoPaths.Count == 0)
            {
                if (_argPaths.Any(fsi => fsi is DirectoryInfo))
                {
                    throw new ArgProcessUserException($"no demos found, maybe try searching subfolders using '{OptRecursive.DefaultAliases[0]}'.");
                }
                throw new ArgProcessUserException("no demos found!");
            }

            // Shorten the paths of the demos if possible, the shared path between the first and last paths will give
            // the overall shared path of everything. If it's empty then we know the demos span multiple drives.
            string commonParent = Utils.SharedPathSubstring(_demoPaths.Min.FullName, _demoPaths.Max.FullName);
            IEnumerable <(FileInfo demoPath, string displayName)> paths =
                _demoPaths.Select(demoPath => (
                                      demoPath,
                                      commonParent == ""
                                                ? demoPath.FullName
                                                : PathExt.GetRelativePath(commonParent, demoPath.FullName)
                                      ));

            using DemoParsingInfo parsingInfo = new DemoParsingInfo(setupInfo, paths.ToImmutableList());
            Process(parsingInfo);
        }