| 522 | } |
| 523 | |
| 524 | static void RunScan(const std::string& directory, int threadCount, bool verbose, bool jsonOutput) |
| 525 | { |
| 526 | auto startTime = std::chrono::steady_clock::now(); |
| 527 | std::vector<ScanItem> items; |
| 528 | int pboCount = 0; |
| 529 | |
| 530 | std::cout << "Scanning " << directory << " ..." << std::endl; |
| 531 | |
| 532 | for (auto& entry : fs::recursive_directory_iterator(directory, fs::directory_options::skip_permission_denied)) |
| 533 | { |
| 534 | try |
| 535 | { |
| 536 | if (!entry.is_regular_file()) |
| 537 | continue; |
| 538 | |
| 539 | std::string path = entry.path().string(); |
| 540 | std::string ext = entry.path().extension().string(); |
| 541 | for (auto& c : ext) |
| 542 | c = static_cast<char>(tolower(static_cast<unsigned char>(c))); |
| 543 | |
| 544 | std::error_code ec; |
| 545 | int64_t fileSize = static_cast<int64_t>(entry.file_size(ec)); |
| 546 | if (ec) |
| 547 | fileSize = 0; |
| 548 | |
| 549 | if (ext == ".pbo") |
| 550 | { |
| 551 | ScanItem pboItem; |
| 552 | pboItem.path = path; |
| 553 | pboItem.extension = ext; |
| 554 | pboItem.size = fileSize; |
| 555 | pboItem.category = FileCategory::Pbo; |
| 556 | items.push_back(pboItem); |
| 557 | std::string bankName = path.substr(0, path.size() - 4); // strip .pbo |
| 558 | QFBank bank; |
| 559 | if (bank.open(RString(bankName.c_str()))) |
| 560 | { |
| 561 | bank.Lock(); |
| 562 | if (!bank.error()) |
| 563 | { |
| 564 | PboCollectorCtx ctx{path, &items}; |
| 565 | bank.ForEach(CollectPboEntry, &ctx); |
| 566 | pboCount++; |
| 567 | } |
| 568 | bank.Unlock(); |
| 569 | } |
| 570 | } |
| 571 | else |
| 572 | { |
| 573 | ScanItem item; |
| 574 | item.path = path; |
| 575 | item.extension = ext; |
| 576 | item.size = fileSize; |
| 577 | item.category = CategorizeByExtension(ext); |
| 578 | items.push_back(std::move(item)); |
| 579 | } |
| 580 | } |
| 581 | catch (const std::exception& e) |
no test coverage detected