| 638 | |
| 639 | |
| 640 | void Content::searchFilesAsync(String path, std::vector<std::string>&& exts, std::unordered_map<std::string, int>&& extensionLevels, std::vector<std::string>&& globs, String pattern, bool useRegex, bool caseSensitive, bool includeContent, int contentWindow, const std::function<bool(SearchResult&&)>& callbackFunc) { |
| 641 | auto notifyDone = [&]() { |
| 642 | SearchResult done; |
| 643 | callbackFunc(std::move(done)); |
| 644 | }; |
| 645 | std::string searchRoot = path.empty() ? _assetPath : path.toString(); |
| 646 | if (!SharedContent.exist(searchRoot)) { |
| 647 | notifyDone(); |
| 648 | return; |
| 649 | } |
| 650 | auto filesList = Content::glob(searchRoot, std::move(globs), std::move(extensionLevels)); |
| 651 | if (filesList.empty()) { |
| 652 | notifyDone(); |
| 653 | return; |
| 654 | } |
| 655 | |
| 656 | std::string patternStr = pattern.toString(); |
| 657 | std::string normalizedPattern; |
| 658 | normalizedPattern.reserve(patternStr.size()); |
| 659 | for (size_t i = 0; i < patternStr.size(); ++i) { |
| 660 | if (patternStr[i] == '\\') { |
| 661 | if (i + 1 >= patternStr.size()) continue; |
| 662 | char next = patternStr[i + 1]; |
| 663 | bool keepEscape = false; |
| 664 | if (useRegex) { |
| 665 | keepEscape = |
| 666 | next == '\\' || next == '^' || next == '$' || next == '.' || |
| 667 | next == '*' || next == '+' || next == '?' || next == '[' || |
| 668 | next == ']' || next == 'd' || next == 'D' || next == 'w' || |
| 669 | next == 'W' || next == 's' || next == 'S'; |
| 670 | } else { |
| 671 | keepEscape = |
| 672 | next == '\\' || next == '\'' || next == '"' || next == '/' || |
| 673 | next == 'b' || next == 'f' || next == 'n' || next == 'r' || |
| 674 | next == 't' || next == '0'; |
| 675 | } |
| 676 | if (!keepEscape) continue; |
| 677 | } |
| 678 | normalizedPattern.push_back(patternStr[i]); |
| 679 | } |
| 680 | patternStr = std::move(normalizedPattern); |
| 681 | if (patternStr.empty()) { |
| 682 | notifyDone(); |
| 683 | return; |
| 684 | } |
| 685 | |
| 686 | std::vector<std::string> files; |
| 687 | { |
| 688 | std::unordered_set<std::string> extSet; |
| 689 | extSet.reserve(exts.size()); |
| 690 | for (const auto& ext_ : exts) { |
| 691 | auto ext = Slice(ext_); |
| 692 | if (!ext.empty() && ext.front() == '.') ext.skip(1); |
| 693 | if (!ext.empty()) extSet.insert(ext.toLower()); |
| 694 | } |
| 695 | files.reserve(filesList.size()); |
| 696 | for (const auto& file : filesList) { |
| 697 | if (!extSet.empty()) { |
no test coverage detected