update io::path::normalized()

This commit is contained in:
MihailRis 2025-02-05 14:56:45 +03:00
parent 596132ebe2
commit b1740bf7eb
3 changed files with 63 additions and 23 deletions

View File

@ -10,29 +10,69 @@ void path::checkValid() const {
} }
} }
path path::parent() const {
size_t length = str.length();
while (length && str[length-1] == '/') {
length--;
}
size_t slashpos = length;
slashpos = str.rfind('/', slashpos-1);
if (length >= 2 && str.rfind("..") == length - 2) {
return normalized().parent();
}
if (slashpos == std::string::npos) {
return colonPos == std::string::npos ? "" : str.substr(0, colonPos+1);
}
while (slashpos && str[slashpos-1] == '/') {
slashpos--;
}
return str.substr(0, slashpos);
}
path path::normalized() const { path path::normalized() const {
io::path path = pathPart(); io::path path = pathPart();
std::stack<std::string> parts; std::stack<io::path> parts;
do { int64_t pos = 0;
parts.push(path.name()); int64_t prev = pos-1;
path.str = path.parent().string(); while (pos < path.str.length()) {
} while (!path.empty()); pos = path.str.find('/', pos);
if (pos == std::string::npos) {
while (!parts.empty()) { parts.push(path.str.substr(prev + 1));
const std::string part = parts.top(); break;
parts.pop(); }
if (part == ".") { if (pos - prev == 0) {
prev = pos;
pos = prev + 1;
continue; continue;
} }
if (part == "..") { auto token = path.str.substr(prev + 1, pos - (prev + 1));
throw access_error("entry point reached"); prev = pos;
if (token == ".") {
continue;
} else if (token == "..") {
if (parts.empty()) {
throw access_error("entry-point reached");
}
parts.pop();
continue;
} }
parts.push(std::move(token));
path = path / part;
} }
if (path.colonPos != std::string::npos) { bool started = false;
path = path.entryPoint() + ":" + path.string();
path = "";
while (!parts.empty()) {
const auto& token = parts.top();
if (path.empty()) {
path = token;
} else {
path = token / path;
}
parts.pop();
}
if (colonPos != std::string::npos) {
path = str.substr(0, colonPos+1) + path.string();
} }
return path; return path;
} }

View File

@ -115,13 +115,7 @@ namespace io {
} }
/// @brief Get parent path /// @brief Get parent path
path parent() const { path parent() const;
size_t slashpos = str.rfind('/');
if (slashpos == std::string::npos) {
return colonPos == std::string::npos ? "" : str;
}
return str.substr(0, slashpos);
}
path normalized() const; path normalized() const;

View File

@ -12,3 +12,9 @@ TEST(Path, Path) {
EXPECT_EQ(p / "child", "entry_point:path/file.ext/child"); EXPECT_EQ(p / "child", "entry_point:path/file.ext/child");
EXPECT_EQ(p.parent(), "entry_point:path"); EXPECT_EQ(p.parent(), "entry_point:path");
} }
TEST(Path, DotElements) {
io::path p("entry_point:a/b/c/../../d/e/../");
EXPECT_EQ(p.normalized(), "entry_point:a/d");
EXPECT_EQ(io::path("test:a///b//////c/").parent(), io::path("test:a///b"));
}