From b80517ab159277c360a38ee0220fb3022952b587 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 4 Oct 2022 09:10:58 +0200 Subject: [PATCH] sys: Improved UTF-8 path handling in various places Fixes #768 --- lib/libimhex/include/hex/helpers/fs.hpp | 2 +- lib/libimhex/include/hex/helpers/utils.hpp | 7 +++++++ lib/libimhex/source/api/plugin_manager.cpp | 5 +++-- lib/libimhex/source/helpers/file.cpp | 8 ++++---- lib/libimhex/source/helpers/magic.cpp | 2 +- lib/libimhex/source/helpers/net.cpp | 2 +- main/source/init/tasks.cpp | 8 ++++---- main/source/window/win_window.cpp | 2 +- main/source/window/window.cpp | 10 +++++----- .../source/content/providers/disk_provider.cpp | 13 +++++++------ .../source/content/providers/file_provider.cpp | 9 +++++---- .../source/content/providers/intel_hex_provider.cpp | 7 ++++--- .../content/providers/motorola_srec_provider.cpp | 6 +----- plugins/builtin/source/content/settings_entries.cpp | 6 +++--- plugins/builtin/source/content/tools_entries.cpp | 10 ++++++---- plugins/builtin/source/content/ui_items.cpp | 2 +- plugins/builtin/source/content/views/view_about.cpp | 2 +- .../builtin/source/content/views/view_constants.cpp | 2 +- .../source/content/views/view_pattern_editor.cpp | 4 ++-- plugins/builtin/source/content/views/view_yara.cpp | 6 +++--- 20 files changed, 61 insertions(+), 52 deletions(-) diff --git a/lib/libimhex/include/hex/helpers/fs.hpp b/lib/libimhex/include/hex/helpers/fs.hpp index 862835c3a..6b5c504cc 100644 --- a/lib/libimhex/include/hex/helpers/fs.hpp +++ b/lib/libimhex/include/hex/helpers/fs.hpp @@ -68,7 +68,7 @@ namespace hex::fs { } static inline bool isSubPath(const std::fs::path& base, const std::fs::path& destination) { - const auto relative = std::fs::relative(destination, base).string(); + const auto relative = std::fs::relative(destination, base).u8string(); return relative.size() == 1 || (relative[0] != '.' && relative[1] != '.'); } diff --git a/lib/libimhex/include/hex/helpers/utils.hpp b/lib/libimhex/include/hex/helpers/utils.hpp index 4753e2a92..4cbcaf782 100644 --- a/lib/libimhex/include/hex/helpers/utils.hpp +++ b/lib/libimhex/include/hex/helpers/utils.hpp @@ -275,6 +275,13 @@ namespace hex { return iter != a.end(); } + template requires requires(T t) { t.u8string(); } + std::string toUTF8String(const T &value) { + auto result = value.u8string(); + + return { result.begin(), result.end() }; + } + template T get_or(const std::variant &variant, T alt) { const T *value = std::get_if(&variant); diff --git a/lib/libimhex/source/api/plugin_manager.cpp b/lib/libimhex/source/api/plugin_manager.cpp index 6bc78d3f5..3f902485f 100644 --- a/lib/libimhex/source/api/plugin_manager.cpp +++ b/lib/libimhex/source/api/plugin_manager.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -16,7 +17,7 @@ namespace hex { return; } #else - this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY); + this->m_handle = dlopen(hex::toUTF8String(path).c_str(), RTLD_LAZY); if (this->m_handle == nullptr) { log::error("dlopen failed: {}!", dlerror()); @@ -68,7 +69,7 @@ namespace hex { bool Plugin::initializePlugin() const { const auto requestedVersion = getCompatibleVersion(); if (requestedVersion != IMHEX_VERSION) { - log::error("Refused to load plugin '{}' which was built for a different version of ImHex: '{}'", this->m_path.filename().string(), requestedVersion); + log::error("Refused to load plugin '{}' which was built for a different version of ImHex: '{}'", hex::toUTF8String(this->m_path.filename()), requestedVersion); return false; } diff --git a/lib/libimhex/source/helpers/file.cpp b/lib/libimhex/source/helpers/file.cpp index 9e13a99c6..5e3dda5c0 100644 --- a/lib/libimhex/source/helpers/file.cpp +++ b/lib/libimhex/source/helpers/file.cpp @@ -17,12 +17,12 @@ namespace hex::fs { this->m_file = _wfopen(path.c_str(), L"w+b"); #else if (mode == File::Mode::Read) - this->m_file = fopen64(path.string().c_str(), "rb"); + this->m_file = fopen64(hex::toUTF8String(path).c_str(), "rb"); else if (mode == File::Mode::Write) - this->m_file = fopen64(path.string().c_str(), "r+b"); + this->m_file = fopen64(hex::toUTF8String(path).c_str(), "r+b"); if (mode == File::Mode::Create || (mode == File::Mode::Write && this->m_file == nullptr)) - this->m_file = fopen64(path.string().c_str(), "w+b"); + this->m_file = fopen64(hex::toUTF8String(path).c_str(), "w+b"); #endif } @@ -159,7 +159,7 @@ namespace hex::fs { bool File::remove() { this->close(); - return std::remove(this->m_path.string().c_str()) == 0; + return std::remove(hex::toUTF8String(this->m_path).c_str()) == 0; } void File::disableBuffering() { diff --git a/lib/libimhex/source/helpers/magic.cpp b/lib/libimhex/source/helpers/magic.cpp index 6539b4dfa..1a11315ca 100644 --- a/lib/libimhex/source/helpers/magic.cpp +++ b/lib/libimhex/source/helpers/magic.cpp @@ -27,7 +27,7 @@ namespace hex::magic { for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Magic)) { for (const auto &entry : std::fs::directory_iterator(dir, error)) { if (entry.is_regular_file() && ((sourceFiles && entry.path().extension().empty()) || (!sourceFiles && entry.path().extension() == ".mgc"))) { - magicFiles += fs::toShortPath(entry.path()).string() + MAGIC_PATH_SEPARATOR; + magicFiles += hex::toUTF8String(fs::toShortPath(entry.path())) + MAGIC_PATH_SEPARATOR; } } } diff --git a/lib/libimhex/source/helpers/net.cpp b/lib/libimhex/source/helpers/net.cpp index 6bc3c4e47..61e869d30 100644 --- a/lib/libimhex/source/helpers/net.cpp +++ b/lib/libimhex/source/helpers/net.cpp @@ -188,7 +188,7 @@ namespace hex { curl_mime *mime = curl_mime_init(this->m_ctx); curl_mimepart *part = curl_mime_addpart(mime); - auto fileName = filePath.filename().string(); + auto fileName = hex::toUTF8String(filePath.filename()); curl_mime_data_cb(part, file.getSize(), [](char *buffer, size_t size, size_t nitems, void *arg) -> size_t { auto file = static_cast(arg); diff --git a/main/source/init/tasks.cpp b/main/source/init/tasks.cpp index 6611b919d..0b6656746 100644 --- a/main/source/init/tasks.cpp +++ b/main/source/init/tasks.cpp @@ -78,7 +78,7 @@ namespace hex::init { try { fs::createDirectories(folder); } catch (...) { - log::error("Failed to create folder {}!", folder.string()); + log::error("Failed to create folder {}!", hex::toUTF8String(folder)); result = false; } } @@ -135,7 +135,7 @@ namespace hex::init { cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true; cfg.SizePixels = fontSize; - fonts->AddFontFromFileTTF(fontFile.string().c_str(), std::floor(fontSize), &cfg, ranges.Data); // Needs conversion to char for Windows + fonts->AddFontFromFileTTF(hex::toUTF8String(fontFile).c_str(), std::floor(fontSize), &cfg, ranges.Data); // Needs conversion to char for Windows } cfg.MergeMode = true; @@ -244,7 +244,7 @@ namespace hex::init { if (builtinPlugins > 1) continue; if (!plugin.initializePlugin()) { - log::error("Failed to initialize plugin {}", plugin.getPath().filename().string()); + log::error("Failed to initialize plugin {}", hex::toUTF8String(plugin.getPath().filename())); loadErrors++; } } @@ -253,7 +253,7 @@ namespace hex::init { if (plugin.isBuiltinPlugin()) continue; if (!plugin.initializePlugin()) { - log::error("Failed to initialize plugin {}", plugin.getPath().filename().string()); + log::error("Failed to initialize plugin {}", hex::toUTF8String(plugin.getPath().filename())); loadErrors++; } } diff --git a/main/source/window/win_window.cpp b/main/source/window/win_window.cpp index 179b31a49..274e6aa04 100644 --- a/main/source/window/win_window.cpp +++ b/main/source/window/win_window.cpp @@ -43,7 +43,7 @@ namespace hex { if (data == nullptr) break; std::fs::path path = data; - log::info("Opening file in existing instance: {}", path.string()); + log::info("Opening file in existing instance: {}", hex::toUTF8String(path)); EventManager::post(path); break; } diff --git a/main/source/window/window.cpp b/main/source/window/window.cpp index b5b2bca5b..77d5b104e 100644 --- a/main/source/window/window.cpp +++ b/main/source/window/window.cpp @@ -133,13 +133,13 @@ namespace hex { constexpr static auto CrashBackupFileName = "crash_backup.hexproj"; EventManager::subscribe(this, [this](int) { - ImGui::SaveIniSettingsToDisk(this->m_imguiSettingsPath.string().c_str()); + ImGui::SaveIniSettingsToDisk(hex::toUTF8String(this->m_imguiSettingsPath).c_str()); if (!ImHexApi::Provider::isDirty()) return; for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) { - if (ProjectFile::store((std::fs::path(path) / CrashBackupFileName).string())) + if (ProjectFile::store(path / CrashBackupFileName)) break; } }); @@ -378,7 +378,7 @@ namespace hex { const auto filePath = path / "builtin.hexplug"; ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::TextUnformatted(filePath.string().c_str()); + ImGui::TextUnformatted(hex::toUTF8String(filePath).c_str()); ImGui::TableNextColumn(); ImGui::TextUnformatted(fs::exists(filePath) ? ICON_VS_CHECK : ICON_VS_CLOSE); } @@ -746,7 +746,7 @@ namespace hex { } if (!this->m_imguiSettingsPath.empty() && fs::exists(this->m_imguiSettingsPath)) - ImGui::LoadIniSettingsFromDisk(this->m_imguiSettingsPath.string().c_str()); + ImGui::LoadIniSettingsFromDisk(hex::toUTF8String(this->m_imguiSettingsPath).c_str()); ImGui_ImplGlfw_InitForOpenGL(this->m_window, true); @@ -771,7 +771,7 @@ namespace hex { ImNodes::PopAttributeFlag(); ImNodes::PopAttributeFlag(); - ImGui::SaveIniSettingsToDisk(this->m_imguiSettingsPath.string().c_str()); + ImGui::SaveIniSettingsToDisk(hex::toUTF8String(this->m_imguiSettingsPath).c_str()); ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); diff --git a/plugins/builtin/source/content/providers/disk_provider.cpp b/plugins/builtin/source/content/providers/disk_provider.cpp index 9c6da8302..d7926de42 100644 --- a/plugins/builtin/source/content/providers/disk_provider.cpp +++ b/plugins/builtin/source/content/providers/disk_provider.cpp @@ -259,14 +259,14 @@ namespace hex::plugin::builtin::prv { } std::string DiskProvider::getName() const { - return this->m_path.string(); + return hex::toUTF8String(this->m_path); } std::vector> DiskProvider::getDataInformation() const { return { - {"hex.builtin.provider.disk.selected_disk"_lang, this->m_path.string() }, - { "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(this->m_diskSize) }, - { "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(this->m_sectorSize)} + { "hex.builtin.provider.disk.selected_disk"_lang, hex::toUTF8String(this->m_path) }, + { "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(this->m_diskSize) }, + { "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(this->m_sectorSize) } }; } @@ -341,7 +341,7 @@ namespace hex::plugin::builtin::prv { } nlohmann::json DiskProvider::storeSettings(nlohmann::json settings) const { - settings["path"] = this->m_path.string(); + settings["path"] = hex::toUTF8String(this->m_path); return Provider::storeSettings(settings); } @@ -349,7 +349,8 @@ namespace hex::plugin::builtin::prv { void DiskProvider::loadSettings(const nlohmann::json &settings) { Provider::loadSettings(settings); - this->setPath(settings["path"].get()); + auto path = settings["path"].get(); + this->setPath(std::u8string(path.begin(), path.end())); this->reloadDrives(); } diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index 47795fbd6..2bc9bc96a 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -152,13 +152,13 @@ namespace hex::plugin::builtin::prv { } std::string FileProvider::getName() const { - return std::fs::path(this->m_path).filename().string(); + return hex::toUTF8String(this->m_path.filename()); } std::vector> FileProvider::getDataInformation() const { std::vector> result; - result.emplace_back("hex.builtin.provider.file.path"_lang, this->m_path.string()); + result.emplace_back("hex.builtin.provider.file.path"_lang, hex::toUTF8String(this->m_path)); result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize())); if (this->m_fileStatsValid) { @@ -284,11 +284,12 @@ namespace hex::plugin::builtin::prv { void FileProvider::loadSettings(const nlohmann::json &settings) { Provider::loadSettings(settings); - this->setPath(settings["path"].get()); + auto path = settings["path"].get(); + this->setPath(std::u8string(path.begin(), path.end())); } nlohmann::json FileProvider::storeSettings(nlohmann::json settings) const { - settings["path"] = this->m_path.string(); + settings["path"] = hex::toUTF8String(this->m_path); return Provider::storeSettings(settings); } diff --git a/plugins/builtin/source/content/providers/intel_hex_provider.cpp b/plugins/builtin/source/content/providers/intel_hex_provider.cpp index f87410a92..041e71081 100644 --- a/plugins/builtin/source/content/providers/intel_hex_provider.cpp +++ b/plugins/builtin/source/content/providers/intel_hex_provider.cpp @@ -218,7 +218,7 @@ namespace hex::plugin::builtin::prv { } [[nodiscard]] std::string IntelHexProvider::getName() const { - return hex::format("hex.builtin.provider.intel_hex.name"_lang, this->m_sourceFilePath.filename().string()); + return hex::format("hex.builtin.provider.intel_hex.name"_lang, hex::toUTF8String(this->m_sourceFilePath.filename())); } bool IntelHexProvider::handleFilePicker() { @@ -250,11 +250,12 @@ namespace hex::plugin::builtin::prv { void IntelHexProvider::loadSettings(const nlohmann::json &settings) { Provider::loadSettings(settings); - this->m_sourceFilePath = settings["path"].get(); + auto path = settings["path"].get(); + this->m_sourceFilePath = std::u8string(path.begin(), path.end()); } nlohmann::json IntelHexProvider::storeSettings(nlohmann::json settings) const { - settings["path"] = this->m_sourceFilePath.string(); + settings["path"] = hex::toUTF8String(this->m_sourceFilePath); return Provider::storeSettings(settings); } diff --git a/plugins/builtin/source/content/providers/motorola_srec_provider.cpp b/plugins/builtin/source/content/providers/motorola_srec_provider.cpp index 8ebc4840c..19b40638a 100644 --- a/plugins/builtin/source/content/providers/motorola_srec_provider.cpp +++ b/plugins/builtin/source/content/providers/motorola_srec_provider.cpp @@ -1,15 +1,11 @@ #include "content/providers/motorola_srec_provider.hpp" -#include -#include #include #include #include #include -#include - namespace hex::plugin::builtin::prv { namespace motorola_srec { @@ -198,7 +194,7 @@ namespace hex::plugin::builtin::prv { } [[nodiscard]] std::string MotorolaSRECProvider::getName() const { - return hex::format("hex.builtin.provider.motorola_srec.name"_lang, this->m_sourceFilePath.filename().string()); + return hex::format("hex.builtin.provider.motorola_srec.name"_lang, hex::toUTF8String(this->m_sourceFilePath.filename())); } bool MotorolaSRECProvider::handleFilePicker() { diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index 3f4d0cddb..d18bf0fe5 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -315,7 +315,7 @@ namespace hex::plugin::builtin { if (ImGui::IconButton(ICON_VS_FOLDER_OPENED, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { return fs::openFileBrowser(fs::DialogMode::Open, { {"TTF Font", "ttf"} }, [&](const std::fs::path &path) { - fontPath = path.string(); + fontPath = hex::toUTF8String(path); setting = fontPath; }); } @@ -374,7 +374,7 @@ namespace hex::plugin::builtin { } else { for (size_t n = 0; n < userFolders.size(); n++) { const bool isSelected = (currentItemIndex == n); - if (ImGui::Selectable(userFolders.at(n).string().c_str(), isSelected)) { currentItemIndex = n; } + if (ImGui::Selectable(hex::toUTF8String(userFolders.at(n)).c_str(), isSelected)) { currentItemIndex = n; } if (isSelected) { ImGui::SetItemDefaultFocus(); } } ImGui::EndListBox(); @@ -489,7 +489,7 @@ namespace hex::plugin::builtin { for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Resources)) { auto path = dir / "font.ttf"; if (fs::exists(path)) { - log::info("Loading custom front from {}", path.string()); + log::info("Loading custom front from {}", hex::toUTF8String(path)); fontFile = path; break; diff --git a/plugins/builtin/source/content/tools_entries.cpp b/plugins/builtin/source/content/tools_entries.cpp index 5ed04adb6..833bf7e8a 100644 --- a/plugins/builtin/source/content/tools_entries.cpp +++ b/plugins/builtin/source/content/tools_entries.cpp @@ -620,9 +620,11 @@ namespace hex::plugin::builtin { if (response.code == 200) { try { auto json = nlohmann::json::parse(response.body); - links.push_back({ currFile.filename().string(), + links.push_back({ + hex::toUTF8String(currFile.filename()), json["data"]["file"]["url"]["short"], - json["data"]["file"]["metadata"]["size"]["readable"] }); + json["data"]["file"]["metadata"]["size"]["readable"] + }); } catch (...) { View::showErrorPopup("hex.builtin.tools.file_uploader.invalid_response"_lang); } @@ -975,7 +977,7 @@ namespace hex::plugin::builtin { u32 index = 0; for (auto &file : files) { - if (ImGui::Selectable(std::fs::path(file).filename().string().c_str(), index == selectedIndex)) + if (ImGui::Selectable(hex::toUTF8String(file).c_str(), index == selectedIndex)) selectedIndex = index; index++; } @@ -1067,7 +1069,7 @@ namespace hex::plugin::builtin { fs::File input(file, fs::File::Mode::Read); if (!input.isValid()) { - View::showErrorPopup(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, std::fs::path(file).filename().string())); + View::showErrorPopup(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, hex::toUTF8String(file))); return; } diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index a138a6699..c0505f104 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -127,7 +127,7 @@ namespace hex::plugin::builtin { u32 index = 0; for (auto &path : s_selectableFiles) { ImGui::PushID(index); - if (ImGui::Selectable(path.filename().string().c_str(), index == s_selectableFileIndex)) + if (ImGui::Selectable(hex::toUTF8String(path.filename()).c_str(), index == s_selectableFileIndex)) s_selectableFileIndex = index; ImGui::PopID(); diff --git a/plugins/builtin/source/content/views/view_about.cpp b/plugins/builtin/source/content/views/view_about.cpp index ee39a07c2..6bfd70609 100644 --- a/plugins/builtin/source/content/views/view_about.cpp +++ b/plugins/builtin/source/content/views/view_about.cpp @@ -162,7 +162,7 @@ namespace hex::plugin::builtin { ImGui::TableNextColumn(); for (auto &path : fs::getDefaultPaths(type)) - ImGui::TextUnformatted(path.string().c_str()); + ImGui::TextUnformatted(hex::toUTF8String(path).c_str()); } ImGui::EndTable(); diff --git a/plugins/builtin/source/content/views/view_constants.cpp b/plugins/builtin/source/content/views/view_constants.cpp index 4d1ee2b14..3ccd94f4b 100644 --- a/plugins/builtin/source/content/views/view_constants.cpp +++ b/plugins/builtin/source/content/views/view_constants.cpp @@ -54,7 +54,7 @@ namespace hex::plugin::builtin { this->m_constants.push_back(constant); } } catch (...) { - log::error("Failed to parse constants file {}", file.path().string()); + log::error("Failed to parse constants file {}", hex::toUTF8String(file.path())); continue; } } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 7e4f1457d..b9f8423a3 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -675,14 +675,14 @@ namespace hex::plugin::builtin { entries.resize(this->m_possiblePatternFiles.size()); for (u32 i = 0; i < entries.size(); i++) { - entries[i] = std::fs::path(this->m_possiblePatternFiles[i]).filename().string(); + entries[i] = hex::toUTF8String(this->m_possiblePatternFiles[i].filename()); } if (ImGui::BeginListBox("##patterns_accept", ImVec2(-FLT_MIN, 0))) { u32 index = 0; for (auto &path : this->m_possiblePatternFiles) { - if (ImGui::Selectable(path.filename().string().c_str(), index == this->m_selectedPatternFile)) + if (ImGui::Selectable(hex::toUTF8String(path.filename()).c_str(), index == this->m_selectedPatternFile)) this->m_selectedPatternFile = index; index++; } diff --git a/plugins/builtin/source/content/views/view_yara.cpp b/plugins/builtin/source/content/views/view_yara.cpp index dbf8528de..123aa4f93 100644 --- a/plugins/builtin/source/content/views/view_yara.cpp +++ b/plugins/builtin/source/content/views/view_yara.cpp @@ -46,10 +46,10 @@ namespace hex::plugin::builtin { } else { ImGui::BeginDisabled(this->m_matcherTask.isRunning()); { - if (ImGui::BeginCombo("hex.builtin.view.yara.header.rules"_lang, this->m_rules[this->m_selectedRule].first.string().c_str())) { + if (ImGui::BeginCombo("hex.builtin.view.yara.header.rules"_lang, hex::toUTF8String(this->m_rules[this->m_selectedRule].first).c_str())) { for (u32 i = 0; i < this->m_rules.size(); i++) { const bool selected = (this->m_selectedRule == i); - if (ImGui::Selectable(this->m_rules[i].first.string().c_str(), selected)) + if (ImGui::Selectable(hex::toUTF8String(this->m_rules[i].first).c_str(), selected)) this->m_selectedRule = i; if (selected) @@ -203,7 +203,7 @@ namespace hex::plugin::builtin { delete[] ptr; }, - fs::toShortPath(this->m_rules[this->m_selectedRule].second).string().data() + hex::toUTF8String(fs::toShortPath(this->m_rules[this->m_selectedRule].second)).data() ); fs::File file(this->m_rules[this->m_selectedRule].second, fs::File::Mode::Read);