VFS: clarify escape/unescape cannot work on paths

With recent changes, it can only work with file or directory name.
This commit is contained in:
Nekotekina 2020-03-14 16:01:55 +03:00
parent 70cd8afafa
commit 9176ca084c
2 changed files with 24 additions and 24 deletions

View file

@ -283,25 +283,25 @@ using char2 = char8_t;
using char2 = char; using char2 = char;
#endif #endif
std::string vfs::escape(std::string_view path, bool escape_slash) std::string vfs::escape(std::string_view name, bool escape_slash)
{ {
std::string result; std::string result;
if (path.size() > 2 && path.find_first_not_of('.') == umax) if (name.size() > 2 && name.find_first_not_of('.') == umax)
{ {
// Path contains only dots, not allowed on Windows. // Name contains only dots, not allowed on Windows.
result.reserve(path.size() + 2); result.reserve(name.size() + 2);
result += reinterpret_cast<const char*>(u8""); result += reinterpret_cast<const char*>(u8"");
result += path.substr(1); result += name.substr(1);
return result; return result;
} }
// Emulate NTS (limited) // Emulate NTS (limited)
auto get_char = [&](std::size_t pos) -> char2 auto get_char = [&](std::size_t pos) -> char2
{ {
if (pos < path.size()) if (pos < name.size())
{ {
return path[pos]; return name[pos];
} }
else else
{ {
@ -310,19 +310,19 @@ std::string vfs::escape(std::string_view path, bool escape_slash)
}; };
// Escape NUL, LPT ant other trash // Escape NUL, LPT ant other trash
if (path.size() > 2) if (name.size() > 2)
{ {
// Pack first 3 characters // Pack first 3 characters
const u32 triple = std::bit_cast<le_t<u32>, u32>(toupper(path[0]) | toupper(path[1]) << 8 | toupper(path[2]) << 16); const u32 triple = std::bit_cast<le_t<u32>, u32>(toupper(name[0]) | toupper(name[1]) << 8 | toupper(name[2]) << 16);
switch (triple) switch (triple)
{ {
case "COM"_u32: case "COM"_u32:
case "LPT"_u32: case "LPT"_u32:
{ {
if (path.size() >= 4 && path[3] >= '1' && path[4] <= '9') if (name.size() >= 4 && name[3] >= '1' && name[4] <= '9')
{ {
if (path.size() == 4 || path[4] == '.') if (name.size() == 4 || name[4] == '.')
{ {
// Escape first character (C or L) // Escape first character (C or L)
result = reinterpret_cast<const char*>(u8""); result = reinterpret_cast<const char*>(u8"");
@ -336,7 +336,7 @@ std::string vfs::escape(std::string_view path, bool escape_slash)
case "AUX"_u32: case "AUX"_u32:
case "PRN"_u32: case "PRN"_u32:
{ {
if (path.size() == 3 || path[3] == '.') if (name.size() == 3 || name[3] == '.')
{ {
result = reinterpret_cast<const char*>(u8""); result = reinterpret_cast<const char*>(u8"");
} }
@ -346,11 +346,11 @@ std::string vfs::escape(std::string_view path, bool escape_slash)
} }
} }
result.reserve(result.size() + path.size()); result.reserve(result.size() + name.size());
for (std::size_t i = 0, s = path.size(); i < s; i++) for (std::size_t i = 0, s = name.size(); i < s; i++)
{ {
switch (char2 c = path[i]) switch (char2 c = name[i])
{ {
case 0: case 0:
case 1: case 1:
@ -489,17 +489,17 @@ std::string vfs::escape(std::string_view path, bool escape_slash)
return result; return result;
} }
std::string vfs::unescape(std::string_view path) std::string vfs::unescape(std::string_view name)
{ {
std::string result; std::string result;
result.reserve(path.size()); result.reserve(name.size());
// Emulate NTS // Emulate NTS
auto get_char = [&](std::size_t pos) -> char2 auto get_char = [&](std::size_t pos) -> char2
{ {
if (pos < path.size()) if (pos < name.size())
{ {
return path[pos]; return name[pos];
} }
else else
{ {
@ -507,9 +507,9 @@ std::string vfs::unescape(std::string_view path)
} }
}; };
for (std::size_t i = 0, s = path.size(); i < s; i++) for (std::size_t i = 0, s = name.size(); i < s; i++)
{ {
switch (char2 c = path[i]) switch (char2 c = name[i])
{ {
case char2{u8""[0]}: case char2{u8""[0]}:
{ {

View file

@ -12,11 +12,11 @@ namespace vfs
// Convert VFS path to fs path, optionally listing directories mounted in it // Convert VFS path to fs path, optionally listing directories mounted in it
std::string get(std::string_view vpath, std::vector<std::string>* out_dir = nullptr, std::string* out_path = nullptr); std::string get(std::string_view vpath, std::vector<std::string>* out_dir = nullptr, std::string* out_path = nullptr);
// Escape VFS path by replacing non-portable characters with surrogates // Escape VFS name by replacing non-portable characters with surrogates
std::string escape(std::string_view path, bool escape_slash = false); std::string escape(std::string_view name, bool escape_slash = false);
// Invert escape operation // Invert escape operation
std::string unescape(std::string_view path); std::string unescape(std::string_view name);
// Functions in this namespace operate on host filepaths, similar to fs:: // Functions in this namespace operate on host filepaths, similar to fs::
namespace host namespace host