Add ToValidFileName function

This commit is contained in:
Georg Hagen
2024-10-10 14:54:36 +02:00
parent 0c62ba8626
commit 9228010625
2 changed files with 61 additions and 0 deletions

View File

@@ -5,6 +5,8 @@
*/
#include "FsUtils.hpp"
#include <unordered_map>
#include <regex>
namespace fs = std::filesystem;
@@ -88,4 +90,61 @@ namespace OpenVulkano
return size;
}
std::string FsUtils::ToValidFileName(std::string str)
{
// Map of characters to replace with similar looking ones
static const std::unordered_map<char, std::string> replacements = {
{'<', ""}, // Use full-width less than
{'>', ""}, // Use full-width greater than
{':', ""}, // Use modifier letter colon
{'"', ""}, // Use full-width quotation mark
{'/', ""}, // Use fraction slash
{'\\', ""}, // Use big reverse solidus
{'|', ""}, // Use full-width vertical line
{'?', ""}, // Use full-width question mark
{'*', ""}, // Use asterisk operator
};
// Characters to remove (control characters and others that might cause issues)
static const std::regex remove_pattern("[\\x00-\\x1F\\x7F~`!@#$%^&(){}\\[\\]=+,;]");
// Maximum length for many filesystems
static const size_t MAX_LENGTH = 255;
// Replace problematic characters with similar looking ones
for (const auto& [key, value] : replacements) {
size_t pos = 0;
while ((pos = str.find(key, pos)) != std::string::npos) {
str.replace(pos, 1, value);
pos += value.length();
}
}
// Remove other invalid characters
str = std::regex_replace(str, remove_pattern, "");
// Trim leading/trailing spaces and periods
str = std::regex_replace(str, std::regex("^[\\.\\s]+"), "");
str = std::regex_replace(str, std::regex("[\\.\\s]+$"), "");
// Replace multiple spaces with a single space
str = std::regex_replace(str, std::regex("\\s+"), " ");
// Ensure the string isn't empty after sanitization
if (str.empty()) {
str = "unnamed_file";
}
// Truncate if too long, being careful not to cut in the middle of a UTF-8 character
if (str.length() > MAX_LENGTH) {
size_t len = MAX_LENGTH;
while (len > 0 && (str[len] & 0xC0) == 0x80) {
--len;
}
str = str.substr(0, len);
}
return str;
}
}

View File

@@ -20,5 +20,7 @@ namespace OpenVulkano
static bool IsTreeEmpty(const std::filesystem::path& dir);
static ByteSize GetDirSize(const std::filesystem::path& dir);
static std::string ToValidFileName(std::string filename);
};
}