From 58dbff885cc7f772615529c46ee9ddd56250c5dd Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 31 Mar 2025 22:34:24 +0100 Subject: [PATCH] Use std::string_view instead of const char* internally where possible DescribeGameType could return a std::string_view, but I'd rather consistently avoid returning std::string_view to avoid confusion over lifetime issues (even though they're not present in that case). --- src/api/bsa.h | 4 ++-- src/api/game/game.cpp | 14 +++++++------- src/api/helpers/logging.cpp | 8 +++++--- src/api/helpers/text.cpp | 30 +++++++++++++++--------------- src/api/helpers/text.h | 4 +--- src/api/plugin.cpp | 6 +++--- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/api/bsa.h b/src/api/bsa.h index 1f3ca42e..c5898119 100644 --- a/src/api/bsa.h +++ b/src/api/bsa.h @@ -31,8 +31,8 @@ #include namespace loot { -inline constexpr const char* BSA_FILE_EXTENSION = ".bsa"; -inline constexpr const char* BA2_FILE_EXTENSION = ".ba2"; +inline constexpr std::string_view BSA_FILE_EXTENSION = ".bsa"; +inline constexpr std::string_view BA2_FILE_EXTENSION = ".ba2"; std::map> GetAssetsInBethesdaArchive( const std::filesystem::path& archivePath); diff --git a/src/api/game/game.cpp b/src/api/game/game.cpp index 940f1ca0..6d0953c9 100644 --- a/src/api/game/game.cpp +++ b/src/api/game/game.cpp @@ -56,19 +56,19 @@ using loot::GameType; // game's install path. These directories have fixed paths relative to the // game install path (renaming them causes the game launch to fail, or not // find the DLC files). -constexpr const char* MS_FO4_AUTOMATRON_DATA_PATH = +constexpr std::string_view MS_FO4_AUTOMATRON_DATA_PATH = "../../Fallout 4- Automatron (PC)/Content/Data"; -constexpr const char* MS_FO4_CONTRAPTIONS_DATA_PATH = +constexpr std::string_view MS_FO4_CONTRAPTIONS_DATA_PATH = "../../Fallout 4- Contraptions Workshop (PC)/Content/Data"; -constexpr const char* MS_FO4_FAR_HARBOR_DATA_PATH = +constexpr std::string_view MS_FO4_FAR_HARBOR_DATA_PATH = "../../Fallout 4- Far Harbor (PC)/Content/Data"; -constexpr const char* MS_FO4_TEXTURE_PACK_DATA_PATH = +constexpr std::string_view MS_FO4_TEXTURE_PACK_DATA_PATH = "../../Fallout 4- High Resolution Texture Pack/Content/Data"; -constexpr const char* MS_FO4_NUKA_WORLD_DATA_PATH = +constexpr std::string_view MS_FO4_NUKA_WORLD_DATA_PATH = "../../Fallout 4- Nuka-World (PC)/Content/Data"; -constexpr const char* MS_FO4_VAULT_TEC_DATA_PATH = +constexpr std::string_view MS_FO4_VAULT_TEC_DATA_PATH = "../../Fallout 4- Vault-Tec Workshop (PC)/Content/Data"; -constexpr const char* MS_FO4_WASTELAND_DATA_PATH = +constexpr std::string_view MS_FO4_WASTELAND_DATA_PATH = "../../Fallout 4- Wasteland Workshop (PC)/Content/Data"; bool IsMicrosoftStoreInstall(const GameType gameType, diff --git a/src/api/helpers/logging.cpp b/src/api/helpers/logging.cpp index 41712dd0..fc191113 100644 --- a/src/api/helpers/logging.cpp +++ b/src/api/helpers/logging.cpp @@ -24,12 +24,14 @@ #include "api/helpers/logging.h" +#include + #include namespace { using loot::LogLevel; -constexpr const char* LOGGER_NAME = "loot_api_logger"; +constexpr std::string_view LOGGER_NAME = "loot_api_logger"; LogLevel mapFromSpdlog(spdlog::level::level_enum severity) { using spdlog::level::level_enum; @@ -93,12 +95,12 @@ private: } namespace loot { -std::shared_ptr getLogger() { return spdlog::get(LOGGER_NAME); } +std::shared_ptr getLogger() { return spdlog::get(std::string(LOGGER_NAME)); } std::shared_ptr createLogger( std::function callback) { auto sink = std::make_shared(callback); - auto logger = std::make_shared(LOGGER_NAME, sink); + auto logger = std::make_shared(std::string(LOGGER_NAME), sink); logger->set_level(spdlog::level::level_enum::trace); return logger; diff --git a/src/api/helpers/text.cpp b/src/api/helpers/text.cpp index dd77107d..ac4d333c 100644 --- a/src/api/helpers/text.cpp +++ b/src/api/helpers/text.cpp @@ -37,14 +37,14 @@ namespace loot { /* The string below matches timestamps that use forwardslashes for date separators. However, Pseudosem v1.0.1 will only compare the first two digits as it does not recognise forwardslashes as separators. */ -constexpr const char* dateRegex = +constexpr std::string_view dateRegex = R"((\d{1,2}/\d{1,2}/\d{1,4} \d{1,2}:\d{1,2}:\d{1,2}))"; /* The string below matches the range of version strings supported by Pseudosem v1.0.1, excluding space separators, as they make version extraction from inside sentences very tricky and have not been seen "in the wild". */ -constexpr const char* pseudosemVersionRegex = +constexpr std::string_view pseudosemVersionRegex = R"((\d+(?:\.\d+)+(?:[-._:]?[A-Za-z0-9]+)*))" // The string below prevents version numbers followed by a comma from // matching. @@ -53,21 +53,19 @@ constexpr const char* pseudosemVersionRegex = /* The string below matches a number containing one or more digits found at the start of the search string or preceded by 'v' or 'version:. */ -constexpr const char* digitsVersionRegex = R"((?:^|v|version:\s*)(\d+))"; +constexpr std::string_view digitsVersionRegex = R"((?:^|v|version:\s*)(\d+))"; std::vector ExtractBashTags(std::string_view description) { std::vector tags; - static constexpr const char* BASH_TAGS_OPENER = "{{BASH:"; - static constexpr std::size_t BASH_TAGS_OPENER_LENGTH = - std::char_traits::length(BASH_TAGS_OPENER); + static constexpr std::string_view BASH_TAGS_OPENER = "{{BASH:"; size_t startPos = description.find("{{BASH:"); if (startPos == std::string::npos || - startPos + BASH_TAGS_OPENER_LENGTH >= description.length()) { + startPos + BASH_TAGS_OPENER.length() >= description.length()) { return tags; } - startPos += BASH_TAGS_OPENER_LENGTH; + startPos += BASH_TAGS_OPENER.length(); const size_t endPos = description.find("}}", startPos); if (endPos == std::string::npos) { @@ -94,12 +92,15 @@ std::optional ExtractVersion(std::string_view text) { together, and in order to extract the correct one, they must be searched for in order of priority. */ static const std::vector versionRegexes({ - regex(dateRegex, regex::ECMAScript | regex::icase), - regex(std::string(R"(version:?\s)") + pseudosemVersionRegex, + regex( + dateRegex.begin(), dateRegex.end(), regex::ECMAScript | regex::icase), + regex(R"(version:?\s)" + std::string(pseudosemVersionRegex), regex::ECMAScript | regex::icase), - regex(std::string(R"((?:^|v|\s))") + pseudosemVersionRegex, + regex(R"((?:^|v|\s))" + std::string(pseudosemVersionRegex), + regex::ECMAScript | regex::icase), + regex(digitsVersionRegex.begin(), + digitsVersionRegex.end(), regex::ECMAScript | regex::icase), - regex(digitsVersionRegex, regex::ECMAScript | regex::icase), }); std::match_results what; @@ -198,8 +199,7 @@ int CompareFilenames(const ComparableFilename& lhs, // Use CompareStringOrdinal as that will perform case conversion // using the operating system uppercase table information, which (I think) // will give results that match the filesystem, and is not locale-dependent. - int result = CompareStringOrdinal( - lhs.c_str(), -1, rhs.c_str(), -1, true); + int result = CompareStringOrdinal(lhs.c_str(), -1, rhs.c_str(), -1, true); switch (result) { case CSTR_LESS_THAN: return -1; @@ -238,7 +238,7 @@ std::string NormalizeFilename(std::string_view filename) { std::string TrimDotGhostExtension(std::string&& filename) { // If the name passed ends in '.ghost', that should be trimmed. if (boost::iends_with(filename, GHOST_FILE_EXTENSION)) { - return filename.substr(0, filename.length() - GHOST_FILE_EXTENSION_LENGTH); + return filename.substr(0, filename.length() - GHOST_FILE_EXTENSION.length()); } return filename; diff --git a/src/api/helpers/text.h b/src/api/helpers/text.h index 373cdfdb..fdf39af1 100644 --- a/src/api/helpers/text.h +++ b/src/api/helpers/text.h @@ -38,9 +38,7 @@ #endif namespace loot { -inline constexpr const char* GHOST_FILE_EXTENSION = ".ghost"; -inline constexpr std::size_t GHOST_FILE_EXTENSION_LENGTH = - std::char_traits::length(GHOST_FILE_EXTENSION); +inline constexpr std::string_view GHOST_FILE_EXTENSION = ".ghost"; #ifdef _WIN32 typedef std::wstring ComparableFilename; diff --git a/src/api/plugin.cpp b/src/api/plugin.cpp index d248769c..fae1f073 100644 --- a/src/api/plugin.cpp +++ b/src/api/plugin.cpp @@ -625,9 +625,9 @@ Plugin::GetPluginsMetadata(const std::vector& plugins) { std::string GetArchiveFileExtension(const GameType gameType) { if (gameType == GameType::fo4 || gameType == GameType::fo4vr || gameType == GameType::starfield) - return BA2_FILE_EXTENSION; + return std::string(BA2_FILE_EXTENSION); else - return BSA_FILE_EXTENSION; + return std::string(BSA_FILE_EXTENSION); } unsigned int Plugin::GetEspluginGameId(GameType gameType) { @@ -660,7 +660,7 @@ bool hasPluginFileExtension(std::string_view filename, GameType gameType) { if (gameType != GameType::openmw && boost::iends_with(filename, GHOST_FILE_EXTENSION)) { filename = - filename.substr(0, filename.length() - GHOST_FILE_EXTENSION_LENGTH); + filename.substr(0, filename.length() - GHOST_FILE_EXTENSION.length()); } if (boost::iends_with(filename, ".esp") ||