diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-10 00:53:06 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-10 14:38:09 -0400 |
| commit | 86019f825db516d8d5349c271f702dfe69b5fead (patch) | |
| tree | ec91007fa0c857bfd54bb3d1d78ff55daf083928 /view/sharedcache/core/SharedCache.cpp | |
| parent | b00d315524610d8c66af27619e87648bd5d63942 (diff) | |
[SharedCache] Make the shared cache file lookup more straightforward
We already had separated this part out into the `CacheProcessor` but its more like a builder than anything, so this refactors that out into a `SharedCacheBuilder`.
- Separate out the `CacheProcessor` and simplify its implementation
- Move more implementation specific stuff to the shared cache view
- Prepare for more validation of the shared cache to detect irregular or incomplete shared cache information
- Deduplicate a lot of file vs. project file lookup stuff
- Stop copying all images when getting the number of images to log
- Allow user to select another directory to scan for shared cache files, might make this a warning instead to prevent users from relying on this behavior
We will likely follow this commit up soon with better open behavior, maybe open with options can specify a list of cache entry files? Shouldn't be too much effort aside from making the UI modal for that.
Diffstat (limited to 'view/sharedcache/core/SharedCache.cpp')
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 2e902056..717ec6aa 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -537,197 +537,3 @@ std::optional<CacheSymbol> SharedCache::GetSymbolWithName(const std::string& nam return std::nullopt; return GetSymbolAt(it->second); } - -CacheProcessor::CacheProcessor(Ref<BinaryView> view) -{ - m_view = std::move(view); - m_logger = new Logger("SharedCache.Processor", m_view->GetFile()->GetSessionId()); -} - -bool CacheProcessor::ProcessCache(SharedCache& cache) -{ - // If we are in a project, use the project cache processor. - if (m_view->GetFile()->GetProjectFile()) - return ProcessProjectCache(cache); - return ProcessFileCache(cache); -} - -bool CacheProcessor::ProcessFileCache(SharedCache& cache) -{ - // We assume that the binary view location has all the files we need. - // If we ever want to allow users to override the shared cache file location - // we should really make a cache processor constructor with entry file paths. - std::string baseFilePath = m_view->GetFile()->GetOriginalFilename(); - std::string baseFileName = BaseFileName(baseFilePath); - - // If we don't have an original file path, prompt the user to select one. - if (baseFilePath.empty()) - { - if (!GetOpenFileNameInput(baseFilePath, "Please select the base shared cache file")) - { - // User did not give a file, tell them that we will try and scan the file directory. - m_logger->LogWarn("Failed to get original file path, will try and scan the file directory."); - } - // Update so next load we don't need to prompt the user. - // TODO: What happens for a remote project? This will point at what exactly? - m_view->GetFile()->SetOriginalFilename(baseFilePath); - } - - // Add this file to the entries - try - { - auto baseEntry = CacheEntry::FromFile(baseFilePath, baseFileName, CacheEntryType::Primary); - if (!baseEntry.has_value()) - return false; - - // Before we do anything else, add this to the cache so it's available to other entries. - cache.AddEntry(std::move(*baseEntry)); - } - catch (const std::exception& e) - { - // Just return false so the view init can continue. - m_logger->LogErrorF("Failed to load base entry {}... {}", baseFileName, e.what()); - return false; - } - - // Locate all possible related entry files and add them to the cache. - std::filesystem::path basePath = std::filesystem::path(baseFilePath).parent_path(); - for (const auto& entry : std::filesystem::directory_iterator(basePath)) - { - if (!entry.is_regular_file()) - continue; - auto currentFilePath = entry.path().string(); - auto currentFileName = BaseFileName(currentFilePath); - // Skip our base file, obviously. - if (currentFilePath == baseFilePath) - continue; - // Filter files that don't contain the base file name i.e. "dyld_shared_cache_arm64e" - if (currentFilePath.find(baseFileName) == std::string::npos) - continue; - // Skip map files, they contain some nice information... we don't use. - if (entry.path().extension() == ".map") - continue; - // Skip bndb files! - if (entry.path().extension() == ".bndb") - continue; - try - { - auto additionalEntry = CacheEntry::FromFile(currentFilePath, currentFileName, CacheEntryType::Secondary); - if (!additionalEntry.has_value()) - { - m_logger->LogErrorF("Failed to load entry {}...", currentFileName); - continue; - } - - // Add this file as an entry to the cache - cache.AddEntry(std::move(*additionalEntry)); - } - catch (const std::exception& e) - { - m_logger->LogErrorF("Failed to load entry {}... {}", currentFileName, e.what()); - } - } - - return true; -} - -bool CacheProcessor::ProcessProjectCache(SharedCache& cache) -{ - auto baseProjectFile = m_view->GetFile()->GetProjectFile(); - auto baseProjectFileFolder = baseProjectFile->GetFolder(); - std::string baseFilePath = baseProjectFile->GetPathOnDisk(); - std::string baseFileName = baseProjectFile->GetName(); - // This will point to the path on disk for original non-bndb file. - std::string originalFilePath = m_view->GetFile()->GetOriginalFilename(); - - // If we don't have an original file path, prompt the user to select one. - if (originalFilePath.empty()) - { - if (!GetOpenFileNameInput(originalFilePath, "Please select the base shared cache file")) - { - // User did not give a file, tell them that we will try and scan the project directory. - m_logger->LogWarn("Failed to get original file path, will try and scan the project directory."); - } - // Update so next load we don't need to prompt the user. - m_view->GetFile()->SetOriginalFilename(originalFilePath); - } - - // Remove the .bndb extension if present ("dyld_shared_cache_arm64e.bndb" => "dyld_shared_cache_arm64e) - // TODO: This is a little annoying, we need to do this because the file accessor we have is separate - // TODO: from the view file accessor. If we either made it so that we can parse from the BNDB file accessor, - // TODO: or... something better than this. - if (baseFileName.find(".bndb") != std::string::npos) - { - baseFileName = baseFileName.substr(0, baseFileName.size() - 5); - // Search for the backing file. - for (const auto& projectFile : baseProjectFile->GetProject()->GetFiles()) - { - // Skip files not in the same folder. - auto projectFileFolder = projectFile->GetFolder(); - if (baseProjectFileFolder && projectFileFolder) - if (baseProjectFileFolder->GetId() != projectFileFolder->GetId()) - continue; - - auto projectFilePath = projectFile->GetPathOnDisk(); - auto projectFileName = projectFile->GetName(); - if (projectFileName == baseFileName || projectFilePath == originalFilePath) - { - // Use the real file instead. - baseFilePath = projectFilePath; - baseFileName = projectFileName; - baseProjectFile = projectFile; - break; - } - } - } - - // Add this file to the entries - auto baseEntry = CacheEntry::FromFile(baseFilePath, baseFileName, CacheEntryType::Primary); - if (!baseEntry.has_value()) - return false; - - // Before we do anything else, add this to the cache so it's available to other entries. - cache.AddEntry(std::move(*baseEntry)); - - // Enumerate the project files folder to gather the necessary sub caches. - const auto project = baseProjectFile->GetProject(); - const auto folder = baseProjectFile->GetFolder(); - for (const auto& projectFile : project->GetFiles()) - { - auto projectFilePath = projectFile->GetPathOnDisk(); - auto projectFileName = projectFile->GetName(); - auto currentFolder = projectFile->GetFolder(); - // Skip our base project file, obviously. - if (projectFile->GetId() == baseProjectFile->GetId()) - continue; - // Filter files that don't contain the base file name i.e. "dyld_shared_cache_arm64e" - if (projectFileName.find(baseFileName) == std::string::npos) - continue; - // Filter out .map files, they contain some nice info for rebasing... that we don't do. - if (projectFileName.find(".map") != std::string::npos) - continue; - // Filter out .bndb files! - if (projectFileName.find(".bndb") != std::string::npos) - continue; - // If both top level, or we are in the same folder as the base project file add it. - if ((!folder && !currentFolder) || (folder && currentFolder)) - { - try - { - auto additionalEntry = CacheEntry::FromFile(projectFilePath, projectFileName, CacheEntryType::Secondary); - if (!additionalEntry.has_value()) - { - m_logger->LogErrorF("Failed to load entry {}...", projectFileName); - continue; - } - - // Add this file as an entry to the cache - cache.AddEntry(std::move(*additionalEntry)); - } - catch (const std::exception& e) - {} - } - } - - return true; -} |
