Add ToValidFileName function
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user